2009-06-24 38 views
5

Uygulama, iş parçacığı güvenli midir? Eğer değilse, neyi özlüyorum? volatile anahtar kelimesini bir yerde mi olmalıyım? Ya da OnProcessingCompleted yönteminde bir yerde kilit var mı? Öyleyse nerede? C#: İş parçacığı karşılaşma olayları

public abstract class ProcessBase : IProcess 
{ 
    private readonly object completedEventLock = new object(); 

    private event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; 

    event EventHandler<ProcessCompletedEventArgs> IProcess.ProcessCompleted 
    { 
     add 
     { 
      lock (completedEventLock) 
       ProcessCompleted += value; 
     } 
     remove 
     { 
      lock (completedEventLock) 
       ProcessCompleted -= value; 
     } 
    } 

    protected void OnProcessingCompleted(ProcessCompletedEventArgs e) 
    { 
     EventHandler<ProcessCompletedEventArgs> handler = ProcessCompleted; 
     if (handler != null) 
      handler(this, e); 
    } 
} 


Not: soyut bir temel sınıftır çünkü özel olayı ve açık arabirim şeyler var neden nedeni vardır. Ve ondan gelen sınıflar, doğrudan bu olayla ilgili hiçbir şey yapmamalıdır.

+0

(comment yanıtlandı) –

cevap

4

bir event olmaya özel ProcessCompleted üyesi için gerek yoktur) = daha açıkça belirtecek şekilde sınıf sarmalayıcı Eklenenler - bu sadece bir alan olabilir: - her zaman sahada düz gider sınıf içinde Yani event şeyler zaten kayboluyor.

Eğer açık bir kilit nesnesi ile gösterdiğin yaklaşım değildir çok parçacığı güvenli bir alan benzeri bir olay olmasından daha (yani public event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - Tek fark "Bu" kilit olmamasıdır (iyi bir şey hangi - eğer ideal önlemek this üzerinde kilitleme olmalıdır). Eğer çok işleyicisi getirme zaman .. "işleyicisi değişkeni" yaklaşımı doğru biridir, ama yine de side-effects you should be aware of vardır

+0

Sorunu neden özel olayları ve açık olayları kullanmıştım. Hala gerekli değil mi? Ve bu farkla ne demek istiyorsun? Bir olay EventHandler SomeEvent bu olayı otomatik olarak kilitliyor mu? – Svish

+2

Evet; alan benzeri olaylar (yani, açık bir ekleme/çıkarma olmadan bir olay), dahili bir kilitleme (bu) içerir; Dil özelliğinde 10.8.1'e bakınız (MS versiyonu); ancak, bu sınıf içinde kod tarafından atlanır - bkz. http://marcgravell.blogspot.com/2009/02/fun-with-field-like-events.html; * private * olayı gibi, add/remove (ve böylece kilitleme) asla kullanılmaz. Açık bir arayüz uygulaması için, kod gayet iyi ve kilidi kendiniz yapmış olmanız gerekir - ki bu da bir "kilit (bu)" dan - ve muhtemelen daha iyi *. Bununla sabitleyin; -p –

+0

alrighty =) – Svish

5

sen kilitlemek gerekiyor aksi halde en son değere sahip olmayabilirsiniz:

protected void OnProcessingCompleted(ProcessCompletedEventArgs e) 
{ 
    EventHandler<ProcessCompletedEventArgs> handler; 
    lock (completedEventLock) 
    { 
     handler = ProcessCompleted; 
    } 
    if (handler != null) 
     handler(this, e); 
} 

Not biz işleyicileri seti ve ardından bir işleyici abonelikten yürütmek için gidiyoruz karar verdik bir yarış durumu engelleyemedi bu gelmez. Hala çağrılacak, çünkü onu içeren çok noktaya yayın temsilcisini handler değişkenine getirdik.

Bu konuda yapabileceğiniz pek bir şey yok, çünkü işleyicinin artık çağrılmaması gerektiğini fark etmesini sağlayın.

Sadece değil olaylar parçacığı güvenli yapmak için denemek için tartışmasız iyidir - belirttiğiniz abonelik gerektiği olayı yükseltecektir dizisindeki sadece değişim.

+0

Kilidin gerekli olduğuna emin misiniz? Delegeler değişmezdir ve atamalar atomik işlemdir, bu yüzden bence kilit yoktur. – TcKs

+0

Görüşlerimin iletinize bakın. Diş ipi güvenli hale getirmek için kesinlikle kilitlemeye ihtiyacınız var. –

+0

Evet, "ekle" ve "kaldır" işlevindeki kilitler zorunludur. Ama "OnProcessingCompleted" içinde "kilit" kullanmanın yararı nedir? – TcKs

İlgili konular