2012-02-17 37 views
8

Tôi đã làm việc rất nhiều với C# thời gian gần đây, và tôi đã nhận thấy rằng hầu hết các mã làm tăng sự kiện trong mã của công ty tôi được thực hiện như thế này:C# nâng cao sự kiện

EventHandler handler = Initialized; 

if (handler != null) 
{ 
    handler(this, new EventArgs()); 
} 

Tôi thực sự không hiểu tại sao, thay vào đó, bạn có thể không làm chỉ làm điều đó:

if (Initialized != null) 
{ 
    Initialized(this, new EventArgs()); 
} 

EDIT:

một số thực phẩm cho rằng, tôi đã thử làm một vài xét nghiệm về vấn đề này:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Test t = new Test(true); 

      while(true) 
      { 
       t.Ev += new EventHandler(t_Ev); 
       t.Ev -= new EventHandler(t_Ev); 
      } 
     } 

     static void t_Ev(object sender, EventArgs e) 
     { 
     } 
    } 

    public class Test 
    { 
     private readonly bool m_safe; 

     public Test(bool safe) 
     { 
      m_safe = safe; 

      Thread t = new Thread(Go); 
      t.Start(); 
     } 

     private void Go() 
     { 
      while (true) 
      { 
       if(m_safe) 
       { 
        RaiseSafe(); 
       } 
       else 
       { 
        RaiseUnsafe(); 
       } 
      } 
     } 

     public event EventHandler Ev; 

     public void RaiseUnsafe() 
     { 
      if(Ev != null) 
      { 
       Ev(this, EventArgs.Empty); 
      } 
     } 

     public void RaiseSafe() 
     { 
      EventHandler del = Ev; 

      if (del != null) 
      { 
       del(this, EventArgs.Empty); 
      } 
     } 
    } 
} 

Phiên bản không an toàn khiến chương trình gặp sự cố.

+4

Tôi đoán bạn cần phải hỏi những người đã viết mã gốc. –

+2

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

+0

Bài viết tuyệt vời Eric, cảm ơn! – user472875

Trả lời

9

Phiên bản đầu tiên là một nỗ lực để làm cho chuỗi sự kiện an toàn.

Xem C# Events and Thread Safety

Trên thực tế, như đã nói trong phần thảo luận, nó không làm cho thread kiện an toàn. Vì vậy, tôi sẽ sử dụng phiên bản thứ hai ngắn hơn thay thế.

CHỈNH SỬA: sự kiện an toàn chủ đề thực sự khó thực hiện. Nhìn vào what it might look ... Nếu bạn không thực sự giao dịch với nhiều chủ đề đăng ký/hủy đăng ký sự kiện, bạn không nên lãng phí thời gian với thread-an toàn.

+2

heh ... đã cố gắng cho điều đó, nhưng bạn đánh bại tôi với nó :) –

0

Phiên bản thứ hai không an toàn.

if (Initialized != null) 
{ 
    Initialized(this, new EventArgs()); 
} 

Nếu trình xử lý cuối cùng hủy đăng ký sau if (Initialized != null) thì bạn sẽ kết thúc bằng ngoại lệ không có ngoại lệ.

+3

Trên thực tế không phải là phiên bản là threadsafe, tùy thuộc vào định nghĩa của bạn về threadsafe. Chắc chắn, bạn có thể tránh các tham số rỗng, nhưng phiên bản đầu tiên không tránh được * có khả năng gọi một trình xử lý đã bị xóa trên một chuỗi khác. * –

Các vấn đề liên quan