注:Jon Rauschenberger于9月18日在Orlando的VBITS上發表了“Threading with .NET”。本篇技巧選自那次大會的材料。
.NET Framework給所有開發人員提供了強大的線程工具——不管他們運用的是何種語言。VB開發人員首次可以很容易地創建多線程的應用程序,這些應用程序充分利用了Windows平臺的線程功能。運用該功能是相當簡單的。例如下面這個類:
clearcase/" target="_blank" >cc>Public Class Worker Public Sub DoSomeWork() Thread.Sleep(1000) End Sub End Class |
這個簡單的類包含一個單獨的方法,它通過使處于“active”狀態的線程休眠一秒鐘來模擬一件長期運行的任務。如果你需要多次調用該方法,你可以大量生成多個線程并在每個單獨的線程上調用該方法。你需要寫多線程的代碼的所有的類都在System.Threading名字空間中。要運用這些類,你可以用下面的代碼來導入該名字空間:
Imports System.Threading |
如果你需要調用DoSomeWork方法100次,你可以用下面的代碼:
For currentWorkItem = 1 To 100 Dim currentWorker As New Worker() Dim currentThreadStart As New _ ThreadStart( _ AddressOf currentWorker.DoSomeWork) Dim newThread As New _ Thread(currentThreadStart) newThread.Start() Next |
該代碼會為每個請求生成一個新的線程,然后在線程中運行DoSomeWork方法。該代碼的問題是你會生成100個線程來處理100個調用。每個CPU生成的線程超過了25個就會嚴重影響效率。在執行多個線程時,操作系統必須為每個線程安排處理時間。你生成的線程越多,OS就必須花更多的時間為每個線程安排CPU處理時間,CPU用來執行每個線程所做工作的時間就越少。
為了解決這個問題,.NET Framework提供了一個系統線程池,你可以在里面將任務列隊。線程池中包含一系列線程,它們處理內部任務隊列中的請求。缺省情況下,線程池中的最多線程數量是每個CPU 25個。這就是說,不管你在任務隊列中放置了多少請求,所生成的線程數量永遠不會超過CPU的數量乘以25。要運用系統線程池來調用DoSomeWork方法100次,你可以用ThreadPool.QueueUserWorkItem方法。該方法將一個委派(delegate)作為一個輸入參數。當工作線程將一項任務從隊列中取出時,線程將調用委派,并運行你的代碼。
運用系統線程池的第一步就是用下面的代碼創建你想讓線程執行的方法:
Private Sub CallDoWork(ByVal State As Object) Dim currentWorker As New Worker() currentWorker.DoSomeWork() Me.pgbStatus.Value += 1 End Sub |
該方法的定義必須與System.Threading.WaitCallback委派的定義相符。在VB語法中,這就是說,該方法必須被聲明為一個Sub,它采用一個單獨的叫做State的Object參數。接下來,你只需要調用ThreadPool.QueueUserWorkItem方法,傳入CallDoWork方法的地址:
For currentWorkItem = 1 To 100 Dim threadQueueCallback As New _ WaitCallback(AddressOf CallDoWork) ThreadPool.QueueUserWorkItem( _ threadQueueCallback) Next |
注意,ThreadPool這個類是靜態的,所以你不需要創建它的一個實例——你可以只運用它。在運行該代碼時,100條任務會被放在線程池的任務隊列上。然后CLR通過監控隊列中任務數量來管理隊列中的線程數量。在一個單個CPU機器上,會很快生成25個線程并添加到系統線程池中,但這個數量不會超過25個。
運用系統線程池可以讓你控制你的應用程序將會生成的線程數量。對于一些你不能控制的情況(如到達隊列的消息或調用一個Web service的用戶),能夠控制線程數量就顯得很重要了。運用線程池就可以讓你確保你的應用程序的行為是可以預測的,即使它處理的負荷在不斷增加。
關于作者:
Jon Rauschenberger是Clarity的合作伙伴以及技術主管,這是一家位于芝加哥的信息技術咨詢公司,也是Microsoft Solution Provider Partner。Jon經常在大會上發言并為期刊投稿。另外,作為Microsoft的Strategic Design Review委員會的成員,Jon幫助Microsoft Visual Studio及平臺組來策劃他們的產品的未來。Jon的聯系方式是jrausch@claritycon.com。
原文轉自:http://www.anti-gravitydesign.com