1. 程式人生 > >C#中訊息處理機制(事件與委託)

C#中訊息處理機制(事件與委託)

編寫過Windows桌面應用程式的人都知道,微軟的Windows作業系統與應用程式之間的通訊絕大部分是基於訊息迴圈機制的。在VC++中,程式使用GetMessage,TranslateMessage,DispatchMessage語句從訊息佇列中獲取訊息,轉換訊息並且將訊息分發到目標視窗的過程函式,並由過程函式對不同的Windows訊息進行分別處理。

當你將開發平臺轉向C#的時候,由於C#對訊息進行了面向物件的封裝,訊息被封裝成了事件,使我們對訊息傳送機制的理解蒙上了一層迷霧,下面我們就從實際的程式碼著手,抽絲剝繭,逐步瞭解C# WinForm中的訊息處理機制.當我們新建一個WinForm程式後在Program.cs中我們看到Application.Run(new Form1());Application類具有用於啟動和停止應用程式和執行緒以及處理Windows訊息的方法。通過此語句,當前執行緒上開始執行標準應用程式訊息迴圈,並使指定視窗可見,訊息迴圈被封裝進了Application類的Run()靜態方法中。程式結束時呼叫Exit或者ExitThread來停止訊息迴圈,程式也就隨之終止。  

我們為Form1窗體中建立滑鼠點選事件MyClick,程式自動為我們增加一些程式碼。this.MouseClick+=newSystem.Windows.Forms.MouseEventHandler(this.MyClick);上面this.MouseClick是C#中定義的滑鼠單擊事件。它被定義為: public event MouseEventHandler MouseClick;而MouseEventHandler的定義是publicdelegate void MouseEventHandler(object sender, MouseEventArgs e);該語句定義了一個名為MouseEventHandler的委託,那什麼是委託呢?  委託型別可以理解成在C++中的函式指標,但不同的是,委託是完全面向物件的,同時封裝了物件的例項和方法。本質上,委託把一個例項和該例項上的方法函式封裝成一個可呼叫的實體,它是面向物件的、安全的.我們可以把第一句程式碼理解成為this.MouseClick事件添加了一個指向MyClick處理函式的函式指標。C#中事件的處理方法需要使用委託型別對事件進行註冊.當然,你也可以再次呼叫這句語句對事件新增另一個處理函式如MyClick2,這些對該事件的處理會形成處理函式列表。則在程式執行過程中點選滑鼠後在完成MyClick函式後會繼續執行MyClick2函式。

由上我們可以大致猜測其封裝過程: 

Application類將物件傳送過來的訊息從應用程式訊息佇列中提取出來後,分發到相應的窗體,並轉換成事件。NET框架定義了一個特殊的型別(Delegate委託),該型別提供函式指標的功能。這樣,委託就等效於一個型別安全的函式指標或一個回撥函式。C#中通過Delegate委託機制將事件與響應函式的函式地址關聯起來,並形成一種函式指標列表,當訊息到來的時候,即可通過這些函式指標列表逐一呼叫這些響應函式。我們通過以下方法自定義一個事件觸發,來驗證我們以上的猜測。我們通過手動新增程式碼來實現自定義的代理事件(同VC++中的自定義訊息) 

1、宣告事件委託。此處int para僅是方便實驗,代表所需要的引數列表,但要注意引數列表需要和第3步的引數列表相統一。 public delegate void MyEventHandler(int para);

 2、宣告事件,event 關鍵字用於在發行者類中宣告事件,委託MyEventHandler作為事件的型別。 public event MyEventHandler MyEvent;

3、新增事件的處理程式(響應事件的方法)。public void OnMyEvent(int para) { MessageBox.Show(""事件觸發,引數為:""+para);}

 4、將指定的事件處理程式邦定到要處理的事件上(訂閱事件),注意,此語句需要寫在程式執行語句中,如Form_Lord函式內。 this.MyEvent += new MyEventHandler(OnMyEvent);

 5、觸發事件(呼叫事件的觸發方法)。MyEvent(3); 

 6、通過事件委託的回撥,執行我們需要的事件處理程式。彈出訊息框“事件觸發,引數為:3”。

 以上實驗可以得出結論,C#中的訊息通過Application轉換成事件以後,通過以上6個步驟完成了事件與處理程式之間的對應關係,在使用者觸發事件以後,相應的時間處理程式得到準確執行。也可通過以上方法,增加使用者自定義事件。