ThreadPool类提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器
线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程。一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作完成时,线程池中的一个辅助线程就会执行对应的回调函数
托管线程池中的线程为后台线程,即它们的 IsBackground 属性为 true。这意味着在所有的前台线程都已退出后,ThreadPool 线程不会让应用程序保持运行
也可以将与等待操作不相关的工作项排列到线程池。若要请求由线程池中的一个线程来处理工作项,请调用 QueueUserWorkItem 方法。此方法将对将被从线程池中选定的线程调用的方法或委托的引用用作参数。一个工作项排入队列后就无法再取消它。
计时器队列中的计时器以及已注册的等待操作也使用线程池。它们的回调函数也会排列到线程池。
每个进程都有一个线程池。线程池的默认大小为每个可用处理器有 25 个线程。使用 SetMaxThreads 方法可以更改线程池中的线程数。每个线程使用默认的堆栈大小并按照默认的优先级运行
示例代码:
using System; using System.Threading; public class Example { public static void Main() { string str = "param"; ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), str); Thread.Sleep(1000); Console.ReadKey(); } static void ThreadProc(Object stateInfo) { Console.WriteLine(stateInfo); } }
QueueUserWorkItem方法将指定的方法排入队列以便执行,并指定包含该方法所用数据的对象
1.不传递参数
public static bool QueueUserWorkItem(WaitCallback callBack);
2.传递参数
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
如果将方法成功排入队列,则为 true;否则为 false。如果排入队列的方法仅需要单个数据项,可以将数据项强制转换为类型 Object。如果该方法需要多个复杂数据,则必须定义包含这些数据的类。
什么时候使用ThreadPool?
ThreadPool的作用:
另一种将任务项排列到线程池的方法,不过这个任务项是拥有等待操作的任务项
ThreadPool.RegisterWaitForSingleObject 方法 (WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)
注册一个等待 WaitHandle 的委托(将拥有等待操作的任务项排列到线程池中),并指定一个 32 位有符号整数来表示超时值(以毫秒为单位)。
参数
- waitObject
- 类型:System.Threading.WaitHandle
要注册的 WaitHandle。 使用 WaitHandle 而非 Mutex。
- callBack
- 类型:System.Threading.WaitOrTimerCallback
waitObject 参数终止时调用的 WaitOrTimerCallback 委托。
- state
- 类型:System.Object
传递给委托的对象。
- millisecondsTimeOutInterval
- 类型:System.Int32
以毫秒为单位的超时。 如果 millisecondsTimeOutInterval 参数为 0(零),函数将测试对象的状态并立即返回。 如果 millisecondsTimeOutInterval 为 -1,则函数的超时间隔永远不过期。
- executeOnlyOnce
- 类型:System.Boolean
如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为 false,表示每次完成等待操作后都重置计时器,直到注销等待。
返回值
类型:System.Threading.RegisteredWaitHandle
封装本机句柄的 RegisteredWaitHandle。
此方法返回的 RegisteredWaitHandle 使用完毕后,请调用其 RegisteredWaitHandle.Unregister 方法来释放对等待句柄的引用。 我们建议始终调用 RegisteredWaitHandle.Unregister 方法,即使将 executeOnlyOnce 指定为 true 也是如此。 如果调用 RegisteredWaitHandle.Unregister 方法而不是取决于注册的等待句柄的终结器,则垃圾回收的工作效率更高。
RegisterWaitForSingleObject 方法将指定的委托排队到线程池。 当发生以下情况之一时,辅助线程将执行委托:
-
指定对象处于终止状态()。
-
超时间隔已过期。
RegisterWaitForSingleObject 方法检查指定对象的 WaitHandle 的当前状态。 如果对象状态为非终止状态,则此方法将注册一个等待操作。 此等待操作由线程池中的一个线程来执行。 当对象状态变为终止或超时间隔已过期时,委托由辅助线程执行。 如果 timeOutInterval 参数不为 0(零),并且 executeOnlyOnce 参数为 false,则每当事件收到信号或超时间隔过期时都会重置计时器。
using System; using System.Threading; using System.Runtime.CompilerServices; public class ClassForMain { private static int i = 0; public static void Main(string[] args) { //设置WaitHandle的初始状态为非终止状态时,则此方法将注册一个等待操作 AutoResetEvent argv = new AutoResetEvent(false); //将超时值设置为2000毫秒,超时间隔已过期时辅助线程将执行委托 ThreadPool.RegisterWaitForSingleObject(argv, new WaitOrTimerCallback(workitem), null, 2000, false); //设置WaitHandle的状态为终止状态辅助线程将执行委托 argv.Set(); Console.Read(); } public static void workitem(object O, bool signaled) { i += 1; Console.WriteLine("Thread Pool Work Item Invoked:" + i.ToString()); } }
参考文章: