事件是有用户操作而引发的,windows系统是基于消息的事件驱动机制.
比如,用户按下鼠标左键系统会收到 WM_LBUTTONDOWN,windows会根据当前活动的
窗口句柄,将消息从系统的消息队列中派发到相应的程序(线程)的消息队列上,程序
不断的从自己的消息队列中取出消息调用消息处理函数做处理.而消息的到来相当于
事件,对于不同的事件(消息),用不同的处理函数来响应.而.net中只是对此进行了抽象和封装.
从以上原来可以看出:
1.类或对象可以通过事件向其他类或对象通知发生的相关事情.
2.一个事件可以引发多个处理.
3.多个事件可以交给一个对象处理.
4.没有相应的处理对象的事件,永远不会被引发.
下面做一个例子:一个事件引发多个处理对象.
比如在我们有一个新邮件到来时,希望能派发给传真,然后也能打印来处理.那么我们应该这样设计:
1.首先设计当一封新Email到来时我们的事件参数类,这个类包含事件的信息,继承所有事件参数的基类EventArgs;
internal sealed class NewMailEventArgs : EventArgs
{
private readonly String m_from, m_to, m_subject;
public NewMailEventArgs(String from, String to, String subject)
{
m_from = from; m_to = to; m_subject = subject;
}
public String From { get { return m_from; } }
public String To { get { return m_to; } }
public String Subject { get { return m_subject; } }
}
2.我们接着设计MailManager,用来负责处理和管理事件处理的对象.
internal class MailManager
{
public static void Go()
{
MailManager mm = new MailManager();
Fax fax = new Fax(mm);
Paper paper = new Paper(mm);
mm.SimulateNewMail("hull", "happyhu", "I Love You!");
// Force the Fax object to unregister itself with the MailManager
fax.UnRegister(mm);
// Simulate an incoming mail message
mm.SimulateNewMail("hull", "wangli", "Happy Birthday.");
}
private EventHandler<NewMailEventArgs> m_NewMail;
public event EventHandler<NewMailEventArgs> NewMail
{
add
{
Monitor.Enter(m_NewMail);
m_NewMail += value;
Monitor.Exit(m_NewMail);
}
remove
{
Monitor.Enter(m_NewMail);
m_NewMail -= value;
Monitor.Exit(m_NewMail);
}
}
protected virtual void OnNewMail(NewMailEventArgs e)
{
//第一个参数如果和最后一个参数相等,则第一个参数指向第二参数的值,返回的结果为第一个参数原始值,此处为了并发安全以原子的方式获取事件;
// EventHandler<NewMailEventArgs> temp = Interlocked.CompareExchange(ref m_NewMail, null, null);
//调用委托
//if (temp != null) temp(this, e);
e.Raise(this, ref m_NewMail);
}
public void SimulateNewMail(String from, String to, String subjcet)
{
NewMailEventArgs e = new NewMailEventArgs(from, to, subjcet);
OnNewMail(e);
}
}
//EventArgs扩展方法
public static class EventAgrExtensions
{
public static void Raise<T>(this T e, Object sender, ref EventHandler<T> eventDelegate) where T : EventArgs
{
EventHandler<T> temp = Interlocked.CompareExchange(ref eventDelegate, null, null);
if (temp != null) temp(sender, e);
}
}
3,接下来我们设计事件的处理者,包含传真 Fax类 和 Paper类 打印到纸上.
internal sealed class Paper
{
public Paper(MailManager mm)
{
mm.NewMail += SendMsgToPaper;
}
private void SendMsgToPaper(Object sender,NewMailEventArgs e)
{
Console.WriteLine("Sending mail message to pager:");
Console.WriteLine("From={0}, To={1}, Subject={2}", e.From, e.To, e.Subject);
}
public void UnRegister(MailManager mm)
{
mm.NewMail -= SendMsgToPaper;
}
}
internal sealed class Fax
{
public Fax(MailManager mm)
{
mm.NewMail += FaxMsg;
}
private void FaxMsg(Object sender, NewMailEventArgs e)
{
Console.WriteLine("Faxing mail message:");
Console.WriteLine("From={0}, To={1}, Subject={2}", e.From, e.To, e.Subject);
}
public void UnRegister(MailManager mm)
{
mm.NewMail -= FaxMsg;
}
}
最后我们直接调用 MailManager.Go();当有一份新email到达时,Paper对象和Fax对象都做了处理,我们还可加其他的处理方式来扩展;