C#中運用事件實現異步調用


問題引出:

winform程序中的耗時操作,一般不能在UI線程中執行,需要另開線程。往往我們需要在耗時操作結束后將結果顯示在UI上。

以下是Mainform.cs中調用耗時操作的一段代碼:

 

1     Job j = new Job();
2     j.runJob();


這里耗時操作被封裝在類Job中,調用 j.runJob() 開始耗時操作。其中runJob中封裝了開啟新線程執行任務的代碼。

 

Job運行完后需要返回一個結果並顯示在UI上。

顯而易見的方法是,在Job中實例化一個Mainform對象,然后直接在Job中對UI進行修改。這種方法極其不提倡,極大的增加了類之間的耦合性。

可以想到的一種合理的方法,Job類完成了耗時任務之后給調用它的類發送“消息”,”消息“中還包括了應該顯示的結果。Job方還應該做到:只管發送”消息“,而不管發送給誰。這樣就算更換了調用方,Job類的代碼也不需要進行修改。這樣的”消息“在C#中即為”事件“。


方法步驟:

1.在Job類(需要調用其他類中方法的類)中聲明這兩個變量:

 

1         public delegate void FinishHandler(int param);   //聲明委托
2         public event FinishHandler FinishEvent;          //聲明事件


 委托的變量名可隨意命名,括號中定義了要傳遞參數的類型和個數,這里需要傳遞一個int變量。

 第二行事件的類型要於委托的名稱一樣。

 

2.在Job類(需要調用其他類中方法的類)中合適的地方調用事件:

 

1     FinishEvent(score);


合適的地方一般來說就是耗時操作結束,需要返回結果時。

 括號內參數形式與個數要與第一步中定義的一致。

 

3.將事件發生時需要執行的方法注冊到事件中

1     Job j = new Job();    
2     j.FinishEvent += updateData;
3     j.runJob();


當然,updateData的參數形式和個數也和第一步時一樣。

 

分析總結:

梳理一下運行程序時發生了什么。

實際運行時,首先運行的是第3步中的三行代碼。

第二行表示updateData方法會被j對象中的FinishEvent事件觸發。


第三行開始運行耗時任務,Job類在執行到任務結束准備返回數據時,來到了第二步中的那行代碼,此時,會觸發所有注冊了該事件的方法開始執行。
這樣從MainForm的角度看,實現了異步調用,耗時任務的結果通過另一個函數讀取。

從Job類的角度看,調用了另一個類中的方法。

更多應用待之后編程實踐中發現。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM