線程池:
每一個線程預設會被配置設定1MB的記憶體,在C#中,這些都是實打實的配置設定的,當一個線程啟動的時候,為了配置設定臨時堆棧大約需要花費幾百微秒的時間。
線程池通過循環利用線程可以讓你更高效的利用線程。
線程池就像外包的勞務隊一樣,有任務給他們,他們會管理勞務工的一切,你不需要去花時間去找單個勞務工,然後完成任務就解雇她,
對勞務隊而言,勞務工完成了你的這個任務,還是會回到自己的團隊中的,勞務工的管理也不需要你去負責,因為這由勞務隊處理了,
如果任務太多了,勞務隊會自己招一個勞務工,如果還不夠就繼續招,但是如果任務比較少,而勞務工又比較多的話,對不起,勞務隊的管理人員就會解雇一部分勞務工了。
有很多方法可以進入線程池:
借助Task Parallel Library(framework 4.0)
調用ThreadPool.QueueUserWorkItem
借助異步委托。
借助BackgroundWorker.。
下面的一些構造間接的使用了線程池:
WCF,Remoting,Asp.net, asmx web services應用程式。
System.Timers.Timer 和 System.Threading.Timer.
framework的一些異步方法,例如WebClient 類,和大部分BeginXXX方法。
PLINQ
使用線程池的一些問題:
不可以設定一個線程池線程的名字。
線程池線程全部都是背景線程。
阻塞一個線程池線程可能會觸發建立一個新線程,除非你調用ThreadPool.SetMinThreads方法。
通過Thread.CurrentThread.IsThreadPoolThread屬性可以查詢一個線程是否是線程池線程。
實戰ThreadPool
1:通過Task使用線程池:
<a></a>
public static void MainThread()
{
Task<string> task = Task.Factory.StartNew<string>
(() => DownloadString("http://www.google.com"));
//DoSomething
string result = task.Result;
}
static string DownloadString(string uri)
using (var wc = new System.Net.WebClient())
return wc.DownloadString(uri);
當查詢task.Result的時候線程阻塞,等待task傳回Result。
2:通過ThreadPool.QueueUserWorkItem
ThreadPool.QueueUserWorkItem(Go);
ThreadPool.QueueUserWorkItem(Go, 123);
Console.ReadLine();
static void Go(object data)
Console.WriteLine("Hello from the thread pool! " + data);
Output:
Hello from the thread pool!
Hello from the thread pool! 123
3:借助委托的BeginXXX方法:
Func<string, int> method = Work;
method.BeginInvoke("test", Done, method);
static int Work(string s) { return s.Length; }
static void Done(IAsyncResult cookie)
var target = (Func<string, int>)cookie.AsyncState;
int result = target.EndInvoke(cookie);
Console.WriteLine("String length is:" + result);
在這裡将method當作參數進行傳遞後,在cookie的AsyncState中就可以使用傳遞的method了,
因為cookie.AsyncState類型是object,是以需要進行轉換,然後調用EndInvoke方法來擷取結果。
本文轉自LoveJenny部落格園部落格,原文連結:http://www.cnblogs.com/LoveJenny/archive/2011/05/22/2052561.html,如需轉載請自行聯系原作者