2013-08-11 31 views
18

Tôi muốn thông báo một tin nhắn cảnh báo cho bất kỳ người đăng ký nào khi xảy ra bẫy.C# delegate v.s. eventHandler

Mã tôi thực hiện hoạt động tốt thông qua phương thức ủy nhiệm (myDelegate del).

câu hỏi của tôi là ..

  1. tôi muốn biết là nó có giá trị sử dụng EventHandler khấm khá hơn đại biểu? không chắc chắn những gì khác nhau giữa đại biểu và sự kiện chính xác trong trường hợp của tôi?

  2. thông báo (trapinfo t), đó là những gì tôi đã làm ở đây, để lấy thông tin về bẫy. Nhưng có vẻ như đó không phải là một ý tưởng hay. Đọc một số bài học hướng dẫn trực tuyến giới thiệu đối tượng đại diện đi qua, nó có phù hợp với trường hợp của tôi không? Và tôi nên làm gì? Bất kỳ đề xuất?

Thanks a lot :)

Mã của tôi:

public class trapinfo 
    { 
     public string info; 
     public string ip; 
     public string cause; 
    } 

    public class trap 
    { 
     public delegate void myDelegate(trapinfo t); 
     public myDelegate del; 

     trapinfo info = new trapinfo(); 

     public void run() 
     { 
      //While(true) 
      // If a trap occurred, notify the subscriber 
      for (; ;) 
      { 
       Thread.Sleep(500); 
       foreach (myDelegate d in del.GetInvocationList()) 
       { 
        info.cause = "Shut Down"; 
        info.ip = "192.168.0.1"; 
        info.info = "Test"; 
        d.Invoke(info); 
       } 
      } 
     } 
    } 
    public class machine 
    { 
     private int _occuredtime=0; 

     public trapinfo info = new trapinfo(); 
     public void notify(trapinfo t) 
     { 
      ++_occuredtime; 
      info.cause = t.cause; 
      info.info = t.info; 
      info.ip = t.ip; 
      getInfo(); 
     } 
     public void subscribe(trap t) 
     { 
      t.del += new trap.myDelegate(notify); 
     } 
     public void getInfo() 
     { 
      Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}", 
       info.cause, info.info, info.ip,_occuredtime); 
     } 
    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      trap t = new trap(); 
      machine machineA = new machine(); 
      machineA.subscribe(t); 
      t.run(); 
     } 
    } 

Cập nhật 2013-08-12

Làm thế nào về quan sát/quan sát mẫu thiết kế, mà vẻ bề ngoài tuyệt vời cho trường hợp của tôi. (EventHandler) Super-simple example of C# observer/observable with delegates

Trong trường hợp của tôi, máy đăng ký một tin nhắn bẫy. (Thêm máy vào danh sách yêu cầu) Sau khi xảy ra bẫy, hãy gửi tin nhắn đến tất cả các máy đã đăng ký. (Gọi handleEvent để xử lý nó)

Ưu điểm:

  • không quan tâm GetInvocationList() nữa, chỉ cần sử dụng (+ =) và (- =) để quyết định ai bẫy gửi đến.

  • Dễ hiểu logic của chương trình của tôi.

Tôi biết sẽ có một số cách để làm điều đó, nhưng tôi ước tôi có thể phân tích ưu và nhược điểm của nó. Và cảm ơn nhận xét và đề xuất của bạn, điều đó sẽ rất hữu ích!

tôi đọc EventArgs MSDN Điều mà Matthew Watson gợi ý system.eventargs

Dưới đây là bản tổ chức sự kiện của tôi:

public class TrapInfoEventArgs : EventArgs 
{ 
    public int info { get; set; } 
    public string ip { get; set; } 
    public string cause { get; set; } 
} 
public class trap 
{ 
    public event EventHandler<TrapInfoEventArgs> TrapOccurred; 

    protected virtual void OnTrapOccurred(TrapInfoEventArgs e) 
    { 
     EventHandler<TrapInfoEventArgs> handler = TrapOccurred; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 


    public void run() 
    { 
     //While(true) 
     // If a trap occurred, notify the subscriber 
     for (; ;) 
     { 
      Thread.Sleep(500); 
      TrapInfoEventArgs args = new TrapInfoEventArgs(); 
      args.cause = "Shut Down"; 
      OnTrapOccurred(args); 
     } 
    } 
} 
public class machine 
{ 
    public void c_TrapOccurred(object sender, TrapInfoEventArgs e) 
    { 
     Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}", 
      e.cause, e.info, e.ip, DateTime.Now.ToString()); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     trap t = new trap(); 
     machine machineA = new machine(); 
     t.TrapOccurred += machineA.c_TrapOccurred; //notify machine A 
     t.run(); 
    } 
} 
+0

thể trùng lặp của [Hiểu sự kiện và xử lý sự kiện trong C#] (http://stackoverflow.com/questions/803242/understanding-events-and-event-handlers-in-c-sharp) –

Trả lời

16

Sự khác biệt giữa sự kiện và đại biểu là:

khai sự kiện bổ sung thêm một lớp bảo vệ trên thể hiện ủy nhiệm. bảo vệ này ngăn cản khách hàng của các đại biểu từ đặt lại đại biểu và danh sách gọi của nó, và chỉ cho phép thêm hoặc loại bỏ mục tiêu từ danh sách gọi

Xem What are the differences between delegates and events?

2) Như tôi đã thấy thuê bao của bạn nên Người dùng có thể gán "=" nó thay vì thêm "+ =" .Điều này sẽ chỉ định đại biểu mới, do đó, người được ủy quyền trước đó với danh sách yêu cầu sẽ bị mất và người đăng ký trước sẽ không được gọi nữa. Vì vậy, bạn nên sử dụng Sự kiện chắc chắn. hoặc bạn có thể thay đổi mã của mình để làm cho người được ủy quyền của bạn riêng tư và viết các hàm bổ sung để thao tác nó. vì vậy nó sẽ là hành vi sự kiện của riêng bạn.

//preventing direct assignment 
private myDelegate del ; 

    public void AddCallback(myDelegate m){ 
     del += m; 
    } 

    public void RemoveCallback(myDelegate m){ 
     del -= m; 
    } 

    //or 
    public static trap operator +(trap x,myDelegate m){ 
     x.AddCallback(m); 
     return x; 
    } 
    public static trap operator -(trap x, myDelegate m) 
    { 
     x.RemoveCallback(m); 
     return x; 
    } 

//usage 

//t.AddCallback(new trap.myDelegate(notify)); 
    t+=new trap.myDelegate(notify); 
+0

Vì vậy, tôi phải chăm sóc danh sách yêu cầu trong mã được đăng của tôi, phải không? –

+0

bạn cần phải cung cấp các chức năng để thay đổi nó thay vì làm cho nó có thể truy cập trực tiếp.OOP khái niệm đóng gói – qwr

+0

Cảm ơn, tôi nhận được nó :) –

8

Nó là tốt hơn để sử dụng một event ví dụ của bạn.

  • An event được hiểu bởi nhà thiết kế biểu mẫu và WPF, vì vậy bạn có thể sử dụng IDE để đăng ký sự kiện.

  • Khi tăng events, bạn không cần phải viết cách xử lý foreach của riêng mình để lặp qua chúng.

  • events là cách mà hầu hết người lập trình sẽ mong đợi chức năng này được truy cập.

  • Nếu bạn sử dụng một đại biểu, mã tiêu thụ có thể lộn xộn với nó theo cách mà bạn sẽ muốn ngăn chặn (chẳng hạn như đặt lại danh sách yêu cầu của nó). events không cho phép điều đó xảy ra.

Đối với câu hỏi thứ hai của bạn: Sử dụng một event bạn sẽ tạo ra một lớp có nguồn gốc từ EventArgs để giữ dữ liệu, và thông qua đó để sự kiện này khi bạn nâng cao nó. Người tiêu dùng sau đó sẽ có quyền truy cập vào nó.

Xem ở đây để biết chi tiết: http://msdn.microsoft.com/en-us/library/system.eventargs.aspx

+0

cảm ơn, tôi cập nhật mã của tôi sau khi đọc msdn bạn cung cấp :) –

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