背景
ThreadPool是 .NetFramework2.0的功能,Thread功能繁多反而不是特别好用,因此提出线程池的概念;
使用线程池,不需要程序员去销毁线程。线程池中存放多个线程对象,需要的时候从池子里获取,用完之火不用销毁,放回池子。
优点:节约资源,提升性能;管控总数量,防止滥用。
使用ThreadPool开启新线程
方式一:
QueueUserWorkItem 接收一个参数,参数类型是WaitCallback 它是一个无返回值委托,委托函数接收一个obejct类型参数。
官方定义:public delegate void WaitCallback(object state);
WaitCallback callBack = DoSomething;
ThreadPool.QueueUserWorkItem(callBack);
static void DoSomething(object obj)
{
Console.WriteLine("do something");
}
以上代码可以简写如下, waitCallback委托赋值一个匿名方法
WaitCallback waitCallback = arg => Console.WriteLine("dosomething1");
ThreadPool.QueueUserWorkItem(waitCallback);
进一步简写:
ThreadPool.QueueUserWorkItem(e =>
{
Console.WriteLine("do something2");
});
方式二:
QueueUserWorkItem 接收两个参数,第一个参数是WaitCallback 委托类型,第二个参数是object对象,用于传递给委托函数
参数"dosomething3"将传递给委托函数DoSomething
static void DoSomething(object value)
{
Console.WriteLine(value);
}
WaitCallback waitCallback1 = DoSomething;
ThreadPool.QueueUserWorkItem(waitCallback1, "dosomething3");
使用匿名函数进行简写:
ThreadPool.QueueUserWorkItem(e =>
{
DoSomething(e);
}, "dosomething4");
ThreadPool特性
获取线程池中的线程数量
设置线程数量最大值,必须大于及其CPU核数,否则无效
注意:
设置线程池的数量是全局设置的
委托异步调用–Task—Parrallel—async/await 开启的线程全部都是线程池的线程
new Thread创建的线程不受ThreadPool线程池约束,但是会占用线程池的线程数量
ThreadPool.GetMaxThreads(out int workThreads, out int completionPortThreads);
Console.WriteLine(workThreads + " " + completionPortThreads);
ThreadPool.GetMinThreads(out int workerThreadsMin, out int complectionPortThreadsMin);
Console.WriteLine(workerThreadsMin + " " + complectionPortThreadsMin);
ThreadPool.SetMaxThreads(8, 8);//设置的最大值,必须大于CPU核数,否则无效
ThreadPool.SetMinThreads(2, 2);
线程等待
ManualResetEvent 实例在创建线程之前赋值false,
WaitOn()会阻塞主线程,直到被Set后变为true,认为线程执行完毕
ManualResetEvent mreset = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(e =>
{
Thread.Sleep(2000);
Console.WriteLine("dosomething");
mreset.Set();
});
Console.WriteLine("dosomething else...");
Console.WriteLine("dosomething else...");
Console.WriteLine("dosomething else...");
mreset.WaitOne();
Console.WriteLine("task over");