今天我們來談談線程池:
應用程序可以有多個線程,這些線程在休眠狀態中需要耗費大量時間來等待事件發生。其他線程可能進入睡眠狀態,並且僅定期被喚醒以輪循更改或更新狀態信息,然後再次進入休眠狀態。為了簡化對這些線程的管理,.NET框架為每個進程提供了一個線程池,一個線程池有若干個等待操作狀態,當一個等待操作完成時,線程池中的輔助線程會執行回調函數。線程池中的線程由系統管理,程序員不需要費力於線程管理,可以集中精力處理應用程序任務。通過基礎類庫中的ThreadPool類提供一個線程池,該線程池可用於發送工作現,處理異步I/O,代表其他線程等待及處理計時器.ThreadPool類的所有方法都是靜態方法.ThreadPool本身也是一個靜態類.
我們來看看他的定義和一些常用的方法:
public static class ThreadPool
{
[SecuritySafeCritical]
public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads);
[SecuritySafeCritical]
public static void GetMaxThreads(out int workerThreads, out int completionPortThreads);
[SecuritySafeCritical]
public static void GetMinThreads(out int workerThreads, out int completionPortThreads);
[SecuritySafeCritical]
public static bool QueueUserWorkItem(WaitCallback callBack);
[SecuritySafeCritical]
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
}
GetAvailableThreads這個方法返回的最大線程池線程數和當前活動線程數之間的差值。 參數workerThreads: 可用輔助線程的數目。completionPortThreads: 可用異步I/O 線程的數目。
GetMaxThreads方法獲得當前由線程池維護的輔助線程的最大數目.參數workerThreads: 線程池中輔助線程的最大數目。completionPortThreads: 當前由線程池維護的空閒異步I/O 線程的最大數目。
GetMinThreads方法獲得當前由線程池維護的空閒輔助線程的最小數目.參數workerThreads: 當前由線程池維護的空閒輔助線程的最小數目.completionPortThreads: 當前由線程池維護的空閒異步I/O 線程的最小數目。
QueueUserWorkItem方法將方法排入隊列以便執行。參數callBack, 表示要執行的方法.state:包含方法所用數據的對象。
下面看個例子:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
6
7 namespace ConsoleApplication6
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Console.WriteLine("主線程進行異步條用");
14
15 AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);
16 ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
17 {
18
19 Thread.Sleep(1000);
20 Console.WriteLine("工作任務");
21
22 }));
23 string s="我的參數";
24 ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
25 {
26
27 Thread.Sleep(2000);
28 Console.WriteLine("工作任務1");
29 Console.WriteLine(x);
30
31 }), s);
32 ThreadPool.QueueUserWorkItem(new WaitCallback(MyAsyncOperation), asyncOpIsDone);
33 Console.WriteLine("主線程執行其他");
34 Console.WriteLine("主線程等待任務處理結束");
35 asyncOpIsDone.WaitOne();
36 }
37 static void MyAsyncOperation(Object state)
38 {
39
40 Thread.Sleep(5000);
41 Console.WriteLine("工作任務2");
42 ((AutoResetEvent)state).Set();
43 }
44 }
45 }
運行的結果為 www.2cto.com
這裡有個類為AutoResetEvent,他的作用是通知正在等待的線程已發生事件。他是從EventWaitHandle繼承而來的!例子中分別用了兩種不同的方式調用,第二種是可以傳遞參數的!工作線程1就傳遞了"我的參數"字符串!工作線程2運行完了會通知等待的線程已發生事件.這裡AutoResetEvent初始化的時候首先將信號設成false,工作線程2如果調用成功,將被設成true. asyncOpIsDone.WaitOne()阻塞當前線程,直到收到信號!
再看下面的例子
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
6
7 namespace ConsoleApplication7
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Console.WriteLine("\n當前線程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
14 Console.WriteLine("當前應用域的名字為:{0}", AppDomain.CurrentDomain.FriendlyName);
15 int workerThreads;
16 int completionPortThreads;
17
18 AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);//信號初始為空
19 AutoResetEvent asyncOpIsDone2 = new AutoResetEvent(false);
20 ThreadPool.QueueUserWorkItem(new WaitCallback(MyWork), asyncOpIsDone);
21 ThreadPool.QueueUserWorkItem(new WaitCallback(MyWork1), asyncOpIsDone2);
22 ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
23 Console.WriteLine("得當前由線程池維護的輔助線程的最大數目:{0}", workerThreads);
24 ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
25 Console.WriteLine("得當前由線程池維護的空閒輔助線程的最小數目:{0}", workerThreads);
26 /*WaitHandle[] waithandles = new WaitHandle[2];
27 waithandles[0] = asyncOpIsDone;
28 waithandles[1] = asyncOpIsDone2;
29 WaitHandle.WaitAll(waithandles); */
30 //或者可以這樣
31 asyncOpIsDone.WaitOne();
32 Console.WriteLine("MyWork結束");
33 asyncOpIsDone2.WaitOne();
34 Console.WriteLine("MyWork1結束");
35 }
36 static void MyWork(Object state)
37 {
38 Console.WriteLine("\n當前線程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
39 Console.WriteLine("當前應用域的名字為:{0}", AppDomain.CurrentDomain.FriendlyName);
40 Thread.Sleep(2000);
41 ((AutoResetEvent)state).Set();//表示工作已經完成
42 }
43 static void MyWork1(Object state)
44 {
45 Console.WriteLine("\n當前線程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
46 Console.WriteLine("當前應用域的名字為:{0}", AppDomain.CurrentDomain.FriendlyName);
47 Thread.Sleep(1000);
48 ((AutoResetEvent)state).Set();//表示工作已經完成
49 }
50
51 }
52 }
運行結果為
本例中可以詳細看AutoRestEvent的用法MyWork1實際上先結束的,但是asyncOpIsDone需要等MyWork的信號!所以先輸出了MyWork結束.這裡還有一個東西我想說的就是WaitHandle,上面的例子已經給出了他的用法!他是AutoRsetEvent的基類.
還有ThreadPool有一個函數RegisterWaitForSingleObject這個函數還是滿有意思的!我這裡就不再給出例子了!
好了,今天就到這了!
摘自 ENUO