Microsoft.Net框架程序设计学习笔记(15):事件之原理分析
生活随笔
收集整理的這篇文章主要介紹了
Microsoft.Net框架程序设计学习笔记(15):事件之原理分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
完整定義一個事件的方法
以Mail發送為例:
按.Net框架約定,所有保存事件信息的類型都應該繼承自System.EventArgs,且類型的名稱應該EventArgs結束。
public class MailMsgEventArgs : EventArgs
{
public readonly string from, to, subject, body;
public MailMsgEventArgs(string from, string to, string subject, string body)
{
this.from = from;
this.to = to;
this.subject = subject;
this.body = body;
}
}
按.Net框架約定,委托類型名稱應該以EventHandler結束。另外,回調方法的原型應該有一個void返回值,并且接受兩個參數。第1個參數為Object類型,指向發送通知的對象。第2個參數為一個繼承自EventArgs的類型,其中包括所有通知接受者需要的附加信息。如果我們定義的事件沒有需要傳給事件接受者的附加信息,便不必定義新的委托類型。直接使用FCL中的System.EventHandler,并將EventArgs.Empty傳遞給第二個參數即可。EventHandler的原型為:public delegate void EventHandler(object sender, EventArgs e); public delegate void MailMsgEventHandler(Object sender, MailMsgEventArgs args);
{
if(MailMsg != null)
{
MailMsg(this, e);
}
}
{
MailMsgEventArgs e = new MailMsgEventArgs(from, to, subject, body);
OnMailMsg(e);
}
事件原理分析?
現在讓我們看看定義MailMsg事件時發生了些什么事情?
編譯器在遇到事件定義語句:public event MailMsgEventHandler MailMsg會將這段代碼翻譯成以下3個構造:
//1.一個被初始化為null的私有委托類型字段private MailMsgEventHandler MailMsg = null;
//2.一個允許對象登記事件的公有add_*方法
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void add_MailMsg(MailMsgEventHandler handler)
{
MailMsg = (MailMsgEventHandler)Delegate.Combine(MailMsg, handler);
}
//3.一個允許對象注銷事件的公有remove_*方法
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void remove_MailMsg(MailMsgEventHandler handler)
{
MailMsg = (MailMsgEventHandler)Delegate.Remove(MailMsg, handler);
}
第1步是構造一個委托類型的字段,該字段引用的是一個委托鏈表的首部,鏈表中包含了那些期望在事件發生時被通知的委托對象。當一個偵聽者需要登記事件時,它只需將一個委托實例添加到委托鏈表上就可以了。
注意:登記和注銷事件的方法應用了MethodImplAttribute特性,這個特性使方法被標識為同步方法,這使得它們得以實現線程安全,也就是說多個偵聽者可以同時登記或注銷事件,而不損壞委托鏈表。
偵聽事件
登記、注銷事件代碼示例:
class Fax{
public Fax(MailManager mm)
{
mm.MailMsg += new MailManager.MailMsgEventHandler(FaxMsg); //編譯器將該代碼轉換為: //mm.add_MailMsg(new MailManager.MailMsgEventHandler(FaxMsg)); }
private void FaxMsg(object sender, MailManager.MailMsgEventArgs e)
{
........
}
public void Unregister(MailManager mm)
{
mm.MailMsg -= new MailManager.MailMsgEventHandler(FaxMsg); //編譯器將該代碼轉換為: //mm.remove_MailMsg(new MailManager.MailMsgEventHandler(FaxMsg));
}
}
當一個對象不再希望接受事件通知時,應該注銷該事件。
注意:只要一個對象仍然登記有另一個對象的事件,該對象就不可能被執行垃圾收集。如果我們的類型實現了IDisposable接口的Dispose方法,我們應該在其內部注銷其登記的所有事件。
轉載于:https://www.cnblogs.com/free722/archive/2011/03/27/1997203.html
總結
以上是生活随笔為你收集整理的Microsoft.Net框架程序设计学习笔记(15):事件之原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CKeditor自定义上传图片功能
- 下一篇: Excel文件操作