2009-07-15 29 views
5

bir olay işleyicisi başlatılıyor:C#: Ben bu kod sıralamak bazı yerlerde gördüğüm bir kukla

public event SomeEventHandler SomeEvent = (s, e) => { }; 

mi şeyler yapmanın önerilen bir yol olduğunu? Ne çözer ve kayda değer bir yan etkisi var mı? Hala boş çekler yapmak zorunda mıyım? Ya da daha fazla yapmak zorunda olmadığım şey bu mu? Çöp toplama hala gerektiği gibi çalışacak mı? Örneğin


:

private PropertyChangedEventHandler propertyChanged; 
private readonly object propertyChangedLock = new object(); 
public event PropertyChangedEventHandler PropertyChanged 
{ 
    add 
    { 
     lock (propertyChangedLock) 
      propertyChanged += value; 
    } 
    remove 
    { 
     lock (propertyChanged) 
      propertyChanged -= value; 
    } 
} 
protected void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler; 
    lock (propertyChangedLock) 
     handler = propertyChanged; 

    if (handler != null) 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
} 

ben bu işe ilk satırını değiştirebilir mi:

private PropertyChangedEventHandler propertyChanged = (s, e) => { }; 

Sonra OnPropertyChanged yönteminde boş-denetlemeyi atlamak? Ve sonra null-check'i atlarsam kilidi de atlayabilir miyim? Eğer öyleyse, bunu bana verirdi:

protected void OnPropertyChanged(string propertyName) 
{ 
    propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
} 

Başlatma hesaba katılırken bu güvenli midir? Yoksa özlediğim bazı yan etkiler var mı?

+2

My madde: http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx –

+0

Güzel makale! Diğer bir deyişle, boş çekmeyi kaldırmak bu durumda iş parçacığı güvenli olur. Ancak abonelerin kırılmayan akıllı işleyicileri olması gerekiyor. Bunu doğru mu yaptım? – Svish

cevap

7

Eğer gerçekten yapmak denemek isterseniz, hükümsüzlük denetimlerini yapmak gerekmez iken olay evreli, hala bir kilidin içine getirmesi gerekir:

protected void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler; 
    lock (propertyChangedLock) 
    { 
     handler = propertyChanged; 
    } 
    handler(this, new PropertyChangedEventArgs(propertyName)); 
} 
Aksi

en yeni değer alma olmayabilir - olay işleyicileri farklı bir iş parçacığı eklenir ediliyor, sen teorik olayları yükseltebilir Sonsuza kadar yeni işleyicileri çağırmadan. Pratikte ben hemen her zaman uzak kilidi olmadan alırsınız inanıyorum ama hafıza modeli açısından size çitin bazı tür olmalıdır.

Şahsen ben olaylar evreli yapmak deneyin yapmanızı öneririz. Konuyla ilgili

+0

Yani tüm iş parçacığı güvenli şeyleri atlamak mı istiyorsunuz? – Svish

+0

Evet. Uygun iş parçacığında abone olmak için arayanlar alın. –

+0

Bunu nasıl yaparsınız? – Svish

0

Sen NULL Object pattern bir uygulaması olarak görebilirsiniz.

Size BOŞ yapmanız gerekmez çünkü, kodunuz daha okunabilir hale yardımcı olur - değeri kontrolleri. artık gerekli eğer/mantık kaldırmak için eklenti içinde

kilitler, kalmak zorunda olduğunu söyledi. Bununla hiçbir ilgisi yok. Onlar yarış koşulları önlemek alıştığınız (ancak bunlar çok durumda gerekli eğer ben bilmiyorum)

İlgili konular