天天看點

深入淺出多線程系列之三:線程池

線程池:

每一個線程預設會被配置設定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&lt;string&gt; task = Task.Factory.StartNew&lt;string&gt;

                (() =&gt; 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&lt;string, int&gt; method = Work;

            method.BeginInvoke("test", Done, method);

        static int Work(string s) { return s.Length; }

        static void Done(IAsyncResult cookie)

            var target = (Func&lt;string, int&gt;)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,如需轉載請自行聯系原作者