天天看點

《C#多線程程式設計實戰(原書第2版)》——3.2 線上程池中調用委托

本節書摘來自華章出版社《c#多線程程式設計實戰(原書第2版)》一書中的第3章,第3.2節,作者(美)易格恩·阿格佛溫(eugene agafonov),黃博文 黃輝蘭 譯,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

本節将展示線上程池中如何異步的執行委托。另外,我們将讨論一個叫做異步程式設計模型(asynchronous programming model,簡稱apm)的方式,這是.net曆史中第一個異步程式設計模式。

為了學習本節,你需要安裝visual studio 2015。除此之外無需其他準備。本節的源代碼放置在booksampleschapter3recipe1目錄中。

請執行以下步驟來了解如何線上程池中調用委托:

1.啟動visual studio 2015。建立一個c#控制台應用程式項目。

2.在program.cs檔案中加入以下using指令:

《C#多線程程式設計實戰(原書第2版)》——3.2 線上程池中調用委托

3.在main方法下面加入以下代碼片段:

《C#多線程程式設計實戰(原書第2版)》——3.2 線上程池中調用委托

4.在main方法中加入以下代碼片段:

《C#多線程程式設計實戰(原書第2版)》——3.2 線上程池中調用委托
《C#多線程程式設計實戰(原書第2版)》——3.2 線上程池中調用委托

5.運作程式。

當程式運作時,使用舊的方式建立了一個線程,然後啟動它并等待完成。由于線程的構造函數隻接受一個無任何傳回結果的方法,我們使用了lambda表達式來将對test方法的調用包起來。我們通過列印出thread. currentthread.isthreadpoolthread屬性值來確定該線程不是來自線程池。我們也列印出了受管理的線程id來識别代碼是被哪個線程執行的。

然後定義了一個委托并調用begininvoke方法來運作該委托。begininvoke方法接受一個回調函數。該回調函數在異步操作完成後會被調用,并且一個使用者自定義的狀态會傳給該回調函數。該狀态通常用于區分異步調用。結果,我們得到一個實作了iasyncresult接口的result對象。begininvoke立即傳回了結果,當線程池中的工作者線程在執行異步操作時,仍允許我們繼續其他工作。當需要異步操作的結果時,可以使用begininvoke方法調用傳回的result對象。我們可以使用result對象的iscompleted屬性輪詢結果。但是在本例子中,使用的是asyncwaithandle屬性來等待直到操作完成。當操作完成後,會得到一個結果,可以通過委托調用endinvoke方法,傳遞委托參數和iasyncresult對象。

當操作完成後,傳遞給begininvoke方法的回調函數将被放置到線程池中,确切地說是一個工作者線程中。如果在main方法定義的結尾注釋掉thread.sleep方法調用,回調函數将不會被執行。這是因為當主線程完成後,所有的背景線程會被停止,包括該回調函數。對委托和回調函數的異步調用很可能會被同一個工作者線程執行。通過工作者線程id可以容易地看出。

使用beginoperationname/endoperationname方法和.net中的iasyncresult對象等方式被稱為異步程式設計模型(或apm模式),這樣的方法對稱為異步方法。該模式也被應用于多個.net類庫的api中,但在現代程式設計中,更推薦使用任務并行庫(task parallel library,簡稱tpl)來組織異步api。第4章将會讨論該主題。

繼續閱讀