title: C# delegate v.s. EventHandler
body: <p>I want to send an alert message to any subscribers when a trap occurred.</p>
  
  <p>The code I created works fine using a delegate method <code>myDelegate del</code>.</p>
  
  <p>My questions are:</p>
  
  <ol>
  <li><p>I want to know whether it's better to use <code>EventHandler</code> instead of a delegate?
  I'm not sure what the differences are between a delegate and an <code>EventHandler</code> in my case.</p></li>
  <li><p><code>notify(trapinfo t)</code>, that's what I've done here to get trap information. But it seems not to be a good idea. I read some online tutorial lesson introducing passing delegate object; I'm wondering if it's appropriate in my case? And how should I do it? Any suggestions?</p></li>
  </ol>
  
  <p>Thanks a lot :)</p>
  
  <p><strong>My code:</strong></p>
  
  <pre><code>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("&lt;Alert&gt;: 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();
          }
      }
  </code></pre>
  
  <p><strong>Update 2013-08-12</strong></p>
  
  <p>How about the <a href="https://stackoverflow.com/questions/1249517/super-simple-example-of-c-sharp-observer-observable-with-delegates">observer/observable</a> design pattern, that looks great in my case (<code>EventHandler</code>).</p>
  
  <p>In my case, a machine subscribes to a trap messenger. (Add a machine to an invocation list)
  Once a trap occurred, I send a message to all machines which are subscribed. (Call <code>HandleEvent</code> to handle it)</p>
  
  <p>Advantages:</p>
  
  <ul>
  <li><p>don't care about <code>GetInvocationList()</code> anymore, just use <code>(+=)</code> and <code>(-=)</code> to decide whom to send the trap.</p></li>
  <li><p>It's easier to understand the logic of my program.</p></li>
  </ul>
  
  <p>I know there are several ways to do it, but I wish I could analyze its pros and cons.</p>
  
  <p>And thanks for your comments and suggestions, that would be very helpful!</p>
  
  <p>I read the <a href="https://msdn.microsoft.com/en-us/library/system.eventargs.aspx" rel="nofollow noreferrer">MSDN EventArgs</a> article which Matthew Watson suggested.</p>
  
  <p><strong>Here's my Event Version:</strong></p>
  
  <pre><code>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&lt;TrapInfoEventArgs&gt; TrapOccurred;
  
      protected virtual void OnTrapOccurred(TrapInfoEventArgs e)
      {
          EventHandler&lt;TrapInfoEventArgs&gt; 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("&lt;Alert&gt;: 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();
      }
  }
  </code></pre>