C# 異步編程2 EAP 異步程序開發
在前面一篇博文記錄了C# APM異步編程的知識,今天再來分享一下EAP(基於事件的異步編程模式)異步編程的知識。後面會繼續奉上TPL任務並行庫的知識,喜歡的朋友請持續關註哦。
EAP異步編程算是C#對APM的一種補充,讓異步編程擁有了一系列狀態事件。如果你看過本系列的前一篇文章《C# 異步編程1 APM 異步程序開發》,並假設你是微軟C#語言開發組的一員,現在讓你來設計基於事件的異步編程模式。那你是會利用之前的APM進行改造?還是進行再次創造呢?所以當你對相關dll進行反編譯,會驚喜的發現EAP實際上是對APM增加了事件event後的封裝。因此這篇博文的篇幅不會很長,我們只介紹EAP模式的基本信息和編程實現。對於事件 event 我後續增加博文闡述其功能及用法。
EAP 基於事件的異步編程模式
當我們使用EAP模式進行異步編程時,需要滿足以下2個條件:
1、要進行異步的方法其方法名應該以XXXAsync結尾
2、要有一個名為XXXCompleted的事件監聽異步方法的完成
3、可增加一個CancelAsync方法用於取消正在執行的異步方法(可選)
示例代碼:
/// <summary> /// EAP是對APM的封裝 /// </summary> public class Worker { public enum WorkerStatus { Cancel= 0,Running=1, Completed=2 } public class WorkerEventArgs :EventArgs { public WorkerStatus Status { get; set; } public string Message { get; set; } } public Worker() { } public event EventHandler<WorkerEventArgs> OnWorkCompleted; IAsyncResult asyncResult= null; Thread thread = null; public void WorkAsync() { Worker _this = this; Action action = () => { thread = Thread.CurrentThread; Thread.Sleep(10000); Console.WriteLine(string.Format("線程:{0},Work Over.", Thread.CurrentThread.ManagedThreadId)); }; asyncResult = action.BeginInvoke((result) => { WorkerEventArgs e = null; try { action.EndInvoke(asyncResult); } catch (ThreadAbortException ex) { e = new WorkerEventArgs() { Status = WorkerStatus.Cancel, Message = "異步操作被取消" }; } if (null != _this.OnWorkCompleted) { _this.OnWorkCompleted.Invoke(this, e); } }, this); } public void CancelAsync() { if (null != thread) thread.Abort(); } }
調用程序使用WinForm來進行,示例代碼如下(僅為演示用):
Worker worker; private void Btn_Start_Click(object sender, EventArgs e) { worker = new Worker(); worker.OnWorkCompleted += WorkOver; worker.WorkAsync(); Console.WriteLine(string.Format("線程:{0}", Thread.CurrentThread.ManagedThreadId)); } private void Btn_Cancel_Click(object sender, EventArgs e) { worker.CancelAsync(); } private void WorkOver(object sender, Worker.WorkerEventArgs e) { if (null != e) { if (Worker.WorkerStatus.Cancel == e.Status) { MessageBox.Show(e.Message); } } else { Console.WriteLine(string.Format("線程:{0},委托回調完成.", Thread.CurrentThread.ManagedThreadId)); } }
效果展示:
註意事項(重要):
1、APM異步編程時,因異步代碼執行在單獨的線程中,異步代碼中出現的異常應該在調用EndXXX時捕獲。
2、EAP異步編程時,因上述同樣原因,代碼中的異常信息會被傳遞到Completed事件的EventArgs參數中。
EAP(基於事件的異步編程模式)核心內容並不多,並且如網路、IO等耗時類 Ms 已添加了EAP相關異步功能,我們直接拿來用就好。尤其是後續TPL並行任務的加入,用戶自定義EAP異步功能的機會更是了了,但EAP中相關的知識點如線程、委托、事件等仍然是重要的.......................
TPL任務並行庫正在快馬加鞭趕來中...............
C# 異步編程2 EAP 異步程序開發