Một thực tế phổ biến để tránh điều kiện chủng tộc (trong các ứng dụng đa luồng) khi kích hoạt các sự kiện là:Chủ đề an toàn cho sự kiện kêu gọi
EventHandler<EventArgs> temp = SomeEvent;
if (temp != null) temp(e);
"Remember that delegates are immutable and this is why this technique works in theory. However, what a lot of developers don't realize is that this code could be optimized by the compiler to remove the local temp variable entirely. If this happens, this version of the code is identical to the first version, so a NullReferenceException is still possible."
Vấn đề (theo sách) là "mã này có thể được tối ưu hóa Nếu điều này xảy ra, phiên bản này của mã giống hệt với phiên bản đầu tiên, do đó, một NullReferenceException vẫn có thể "
Theo CLR qua C#, đây là cách tốt hơn để buộc trình biên dịch sao chép con trỏ sự kiện.
virtual void OnNewMail(NewMailEventArgs e)
{
EventHandler<NewMailEventArgs> temp =
Interlocked.CompareExchange(ref NewMail, null, null);
if (temp != null)
temp(this, e);
}
Ở đây, CompareExchange thay đổi tham chiếu NewMail để null nếu nó là null và không làm thay đổi NewMail nếu nó không phải là null. Nói cách khác, CompareExchange không thay đổi giá trị trong NewMail, nhưng nó trả về giá trị bên trong NewMail theo cách nguyên tử, an toàn. Richter, Jeffrey (2010-02-12). CLR qua C# (tr. 265). OReilly Media - A. Kindle Edition.
Tôi đang ở trên .Net 4.0 framework và không chắc chắn điều này có thể hoạt động như thế nào, vì Interlocked.CompareExchange dự kiến tham chiếu đến một vị trí chứ không phải tham chiếu đến sự kiện.
Hoặc có lỗi trong sách hoặc tôi đã giải thích sai nó. Có ai đã triển khai phương pháp này không? Hoặc có cách nào tốt hơn để ngăn chặn điều kiện chủng tộc ở đây?
CẬP NHẬT
đó là lỗi của tôi, mã lặp lại hoạt động. tôi đã có sai quy định đúc, nhưng theo Bradley (dưới đây) nó không phải là cần thiết trong. Net 2.0 và lên trên cửa sổ.
http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx có thể là thú – Vlad