1. 程式人生 > >C# 異步編程2 EAP 異步程序開發

C# 異步編程2 EAP 異步程序開發

異步操作 註意 href images 需要 status {0} 並行任務 監聽

在前面一篇博文記錄了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 異步程序開發