2015-06-01 26 views
5

Internet'teki tüm makaleler, Thread.Abort öğesinin kötülük olduğunu (çünkü eşitleme ilkellerinin işletim sistemine ait olması ve işlemin sonlandırılmadığını ve iş parçacıklarının iptal edilmesinden sonra ilkellerin kilitli kalmaya devam edebileceğini) söylüyor. Geliştiriciler, tüm süreçleri sona erdirmeyi tavsiye eder, çünkü işlem sistemi, işlem durduğunda eşitleme ilkellerini serbest bırakır.İnce senkronizasyon sınıfları, AppDomain başına mı, yoksa Proses başına mı?

  1. Will AppDomain boşaltma yardım, tek Slim senkronizasyon ilkeller kullanacaksa? (.net 4.0 ile iş parçacığıyla ilgili birkaç yeni sınıf eklenmiştir: ManualResetEventSlim, SemaphoreSlim, ReaderWriterLockSlim).

    Dokümantasyon, ilkellerin uygulama kodunun tamamen yönetildiğinden, bu ilkellerin farklı işlemlerde kullanılmayacağını söylüyor. Ama anlamıyorum - bu ilkeller AppDomain sınırında çalışır. (bkz. Can't set synchronization context when using appdomains)

  2. Evet, nasıl yapıyorlar? Hayır ise, o zaman neden dokümantasyon bu sınırlamayı kabul etmiyor?

YUKARI: Tüm kodlarım, kaldırdığım etki alanındaki kod da dahil olmak üzere, tarafımdan güvenilen. Süreç sonlandırıldığında iş parçacığını bırakmak istemiyorum. "Bayrak" ve "güzel mimarlık yapmak" yerine iş parçacığını sonlandırmak (iptal etmek) istiyorum. Önce ek iş parçacığı oluşturmak gerekliyse (bence bu, bir tane daha iş parçacığı oluşturmak için ayrı bir etki alanında arka plan işlemenin başlangıcında gereklidir), yapacağım. "Ayar bayrağı" yaklaşımını kullanmak istemiyorum, çünkü bayrak kontrolleri ile arka plan algoritmasını çalmamı gerektiriyor, çünkü çalışma zamanı veya derleyici benim için o enstrümanı otomatikleştirmeli. Şu anda böyle bir enstrümantasyon yok, bu yüzden yaklaşımı alan adı boşaltma ile uygulamaya çalışıyorum.

Her komut (veya derin iç içe döngülerde) arasında denetim ekleme, kodu önemli ölçüde yavaşlatacaktır. Tesadüfi yerlerde kontrol eklenmesi, sonlandırma garantisi vermez. İptal güvenli kod yazmanın zorlukları çözülebilirse, neden ipleri iptal edip alan adını kaldırmaya çalışmayın?

+1

ile GitHub proje bulabilirim? Seri hale getirilemezler ve "MarshalByRefObject" den miras almazlar. –

+2

AppDomain bu sorunu çözmektedir. Ancak, uygulama alanlarındaki senkronizasyon ilkellerini kullanamazsanız, * her şeyi atmayı göze alabilmeniz gerekir *. –

+0

"Thread.Abort" ile bahsettiğinizden daha fazla sorun var (aslında, thread.Abort' ile bazı eşitleme ilkelleri çok iyi yayınlanır; iş parçacığı aslında elbette ölür). Soru şu, neden ortak iptal yerine agresif kürtajı kullanmaya çalışıyorsunuz? Sadece bir sinyal gönderin ve iş parçacığının iptal edildiğinde ne zaman karar vermesine izin verin. İptal edilen güvenli kod yazılması, hem yönetilen hem de yerel kaynaklar için sadece iş parçacığı için güvenli koddan çok daha zordur. – Luaan

cevap

2

Sen AppDomain, Process ve Thread tanımlarını misunderstands - AppDomains always lives in one process, but one process can be a master for different AppDomains *:

tek bir süreç içinde birden fazla uygulama çalıştırma yeteneği önemli ölçüde sunucu ölçeklenebilirlik artırır.

  • bu sadece söz için, Thread için benzerdir.

Yani, sorunun cevabı böyle mimarisinde hiçbir çapraz süreç çağrıları, çeşitli işlemler için sadece mantıksal bir ayrım olduğu gibi Evet, slim synchronization primitives, çeşitli AppDomains ile çalışacaktır olduğunu.

bağlantılı sorusuna gelince, ya spesifik Thread değil AppDomain -belirli olan sadece SynchronizationContext ile orada senkronizasyon ilkel ile hiçbir sorun yoktur.

Sen AppDomain, Thread ve Process burada arasındaki fark hakkında büyük bir cevap bulabilirsiniz: boşaltma AppDomain gelince Difference between AppDomain, Assembly, Process, and a Thread

, ben içine bir işçiyi Thread başlayabilirsiniz olarak kodunuzu planı ayrı düşünmek senin it mentioned here gibi sistem kaynaklarına sınırlı erişime sahip AppDomain ve tamamlanması için sadece bekleyin, bir şey:

using System; 
using System.Threading; 
using System.Threading.Tasks; 

class Program 
{ 
    static void Main() 
    { 
     var ad = AppDomain.CreateDomain("WhereTheWorkHappens"); 

     Task<string> t = DoWorkInOtherDomain(ad); 
     Console.WriteLine("waiting..."); 
     Console.WriteLine(t.Result); 

     Console.ReadLine(); 
    } 

    static Task<string> DoWorkInOtherDomain(AppDomain ad) 
    { 
     var ch = new MarshaledResultSetter<string>(); 

     Worker worker = (Worker)ad.CreateInstanceAndUnwrap(typeof(Worker).Assembly.FullName, typeof(Worker).FullName); 
     worker.DoWork(ch); 

     return ch.Task; 
    } 

    class Worker : MarshalByRefObject 
    { 
     public void DoWork(MarshaledResultSetter<string> callback) 
     { 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       Thread.SpinWait(500000000); 
       callback.SetResult(AppDomain.CurrentDomain.FriendlyName); 
      }); 
     } 
    } 

    class MarshaledResultSetter<T> : MarshalByRefObject 
    { 
     private TaskCompletionSource<T> m_tcs = new TaskCompletionSource<T>(); 
     public void SetResult(T result) { m_tcs.SetResult(result); } 
     public Task<T> Task { get { return m_tcs.Task; } } 
    } 
} 

sizin için ek bir fikre olarak, yaklaşıkokuyabilir, düşündüğüm gibi, sistem kaynaklarını elle yönetmediğiniz ve güvenilir olmayan kodunuz tarafından saldırıya uğrama olasılığınızın azaldığı için daha iyi bir yaklaşım.

Ayrıca, nasıl AppDomain sınır yoluyla alacağı Cross-AppDomain Marshaling friendly TPL wrappers for APM

+0

Anladığım kadarıyla, AppDomain sadece bir işleme ait ve AppDomain birden fazla işlem içermiyor. SynchronizationContext (ContextBoundObjects için) uygulamasının birkaç AppDomains içermediğini anlıyorum. Neden karar vermiyorsunuz, ben yok muyum? Görünüşe göre, eski yanlış anlaşılmalarınızla savaşıyorsunuz, benim de aynı olduğunu farz ediyorum. Benimki farklıdır! AppDomains arasında nasıl senkronize edileceğini anlamıyorum (OS düzeyinde eşitleme ilkellerini kullanmadan). AppDomain sınırını geçtiğinde iş parçacığına ne olduğunu hala anlamıyorum. – R2D4

+0

Bu soruya bakın - http://stackoverflow.com/questions/21493944/synchronizing-between-appdomains-using-named-mutex Sorunun yanlış olduğunu düşünüyorum. AppDomain'in değil, Konuları senkronize ederiz. Ancak Konular, Uygulama Alanlarına değil, İşlemlere aittir. – R2D4

+0

Sorunuzu cevapladım: Evet, ince sürümler çeşitli 'UygulamaAlanı 'üzerinde çalışacaklar, çünkü çeşitli' Threads' hala ** aynı 'Process' ** içinde oldukları gibi. – VMAtm

İlgili konular