源碼地址:https://github.com/Jackson0714/Threads
原文地址:C#多線程之旅(4)——APM初探
C#多線程之旅目錄:
C#多線程之旅(5)——同步機制介紹
C#多線程之旅(6)——詳解多線程中的鎖
更多文章正在更新中,敬請期待......
C#多線程之旅(4)——APM初探
先交代下背景,前面幾張內容主要是介紹多線程的基本知識,這一章是因為正好接觸到了APM(異步編程模型),發現APM真的很強大,其中有部分知識點涉及到了委托的BeginInvoke/EndInvoke,就由衷地想寫下APM相關的知識。

強大的異步處理模型,不得不被它折服!
一、簡單的串行執行程序


讓我們看看這個程序的運行結果:
二、使用委托來實現APM
2.1 預備知識

/// <summary> /// 定義一個泛型委托 /// </summary> /// <typeparam name="T">輸入參數</typeparam> /// <typeparam name="TResult">返回值</typeparam> /// <param name="arg">輸入參數</param> /// <returns name="TResult">返回值</returns> private delegate TResult Func<T, TResult>(T arg);
對於這個定義,C#編譯器會將這行代碼編譯成一個類定義,它的邏輯定義如下:
public sealed class Func<T, TResult> : MulticastDelegate { public Func(Object obj, IntPtr method); public TResult Invoke(T arg); public IAsyncResult BeginInvoke(T arg, AsyncCallback callback, Object obj); public TResult EndInvoke(IAsyncResult result); }
定義一個委托時,會生成一個BeginInvoke和EndInvoke方法的類。
當定義下面的委托時
public delegate void myDelegate(int value);
通過反編譯工具ILSpy查看結果:
BeginInvoke:
1.第一個參數arg為委托定義相同的參數(可以為兩個參數arg,和委托的簽名相同),可以傳入到委托引用的方法;
2.倒數第二個參數callback為回調方法,當BeginInvoke方法執行完后,會立即調用回調方法,如果callback=null,則不調用回調方法;
3.倒數第一個參數object給EndInvoke用的。
4.返回值為IAsyncResult類型的接口對象(實際上是AsynResult的類型實例)。該接口對象用途
a.傳遞參數,它包含了對調用了BeginInvoke的委托的引用,這里是Add方法的int類型的輸入參數;
b.包含了BeginInvoke()的最后一個Object類型的參數
c.它可以鑒別是哪個方法的哪一次調用,因為通過同一個委托變量可以對同一個方法調用多次。
EndInvoke:
1.第一個參數接收BeginInvoke返回的IAnsyResult;
2.返回的TResult為委托引用的方法的返回值,這里是Add方法的int類型返回值
2.2 用委托來實現APM的原理
2.3 動手寫個實現了APM的Code
通過上面的流程圖,相信我們對委托來實現APM有了一定的理解,再來讀讀code,相信能更快地理解。注釋僅作參考,有問題可以回復我哦!
讓我們看看結果:
注意:
1.必須先將IAsyncResult轉換為AsyncResult,才能獲取到引用的委托,因為它沒有包含在IAsyncResult接口的定義中;
2.Add方法的調用,AddCallback方法都是線程池線程調用的;
3.BeginInvoke的object參數可以為任何類型,例子中傳遞的是string類型的參數"I'm here!";
4.主線程執行的for循環和Add方法中線程是同時進行的,交替打印結果;
5.當異步的Add方法沒有執行完畢,調用EndInvoke,則會阻塞當前線程池線程,只有異步方法執行完畢后,才會繼續執行的代碼;
6.Add方法執行完后,會自動調用回調方法AddCallback;
7.在調用EndInvoke可能拋出異常,所以需要加try/catch/finally,捕獲EndInvoke的可能拋出的異常。
因為只是剛開始接觸APM相關的知識,所以本篇只是寫初探的內容,后面的章節會更多地介紹這方面的內容。希望得到園友們的支持!
作 者: Jackson0714
出 處:http://www.cnblogs.com/jackson0714/
關於作者:專注於微軟平台的項目開發。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
特此聲明:所有評論和私信都會在第一時間回復。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!