I want to notify an alert message to any subscribers when an trap occurred.
The code i made works fine through a delegate method(myDelegate del).
my questions are..
I want to know is it worth using Eventhandler better off delegate? not sure what's different between delegate and event exactly in my case?
notify(trapinfo t), that's what I've done here, to get trap information. But it seems not to be a good idea. Read some online tutorial lesson introducing passing delegates object, is it appropriate to my case? And How should I do? Any suggestions?
Thanks a lot :)
My 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("<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();
}
}
Update 2013-08-12
How about observer/observable design pattern, that looks great to my case. (EventHandler) Super-simple example of C# observer/observable with delegates
In my case, a machine subscribe a trap messenger. (Add machine to a invocation list) Once a trap occurred, send message to all machines which are subscribed. (Call HandleEvent to handle it)
Advantage:
don't care GetInvocationList() anymore, just use (+=) and (-=) to decide who trap send to.
Easily to understand the logic of my program.
I know there would be several ways to do it, but I wish I could analyze its pros and cons. And Thanks for your comments and suggestions, that would be very helpful!
I read MSDN EventArgs Article which Matthew Watson suggests system.eventargs
Here's my Event Version:
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();
}
}
The difference between event and delegate is that :
See What are the differences between delegates and events?
2) As I see your subscriber should not change delegate freely.One subscriber can assign "=" it instead of adding "+=" .This will assign new delegate ,therefore, previous delegate with its invocation list will be lost and previous subscribers will not called anymore. So you should use Event for sure. or you can change your code to make your delegate private and write additional functions for manipulating it .so it will be your own event behavior .
It is much better to use an
event
for your example.An
event
is understood by the Visual Studio Form and WPF designers, so you can use the IDE to subscribe to events.When raising
events
, there is no need for you to write your ownforeach
handling to iterate through them.events
are the way that most programmers will expect this functionality to be accessed.If you use a delegate, the consuming code can mess around with it in ways that you will want to prevent (such as resetting its invocation list).
events
do not allow that to happen.As for your second question: Using an
event
you would create a class derived fromEventArgs
to hold the data, and pass that to the event when you raise it. The consumer will then have access to it.See here for details: http://msdn.microsoft.com/en-us/library/system.eventargs.aspx