线程池 是 clr 管理,每个clr 一个线程池实例
最初 是为了 管理线程创建销毁资源 预先在池子里有一些线程 然后 从里面拿取空闲的线程进行逻辑,用途是用来 执行时间短的一些操作 能够在有限的线程中进行复用 好节省资源,就是 时间换空间 以稍微长的执行时间换取所创建线程所需要的空间资源
另外线程池 ThreadPool拥有一个静态方法QueueUserWorkItem 接收一个委托 然后异步去处理
也就是 第一个 异步实现方式通过委托 也就是 APM 异步编程模式
保持线程中的操作都是短暂的是非常重要的。不要在线程池中放入长时间运行的操作,或者阻塞工作线程。这将导致所有工作线程变得繁忙,从而无法服务用户操作。这会导致性能问题和非常难以调试的错误
请注意线程池中的工作线程都是后台线程。这意味着当所有的前台线程(包括主程序线程)完成后,所有的后台线程将停止工作。
1.如何在线程池中取消执行
CancellationTokenSource cancle 或者 CancellationToken.IsCancellationRequested属性
2.如何在线程池中正确执行等待
一般是通过 结合信号 ManualResetEvent 来阻塞
3.使用System.Threading. Timer对象来在线程池中创建周期性调用的异步
4.通过 BackgroundWorker 事件 进行订阅从而达到异步程序方式 也就是 EAP基于事件驱动的异步
class Program
{
static void Main(string[] args)
{
RunOperations(TimeSpan.FromSeconds(5));
RunOperations(TimeSpan.FromSeconds(7));
}
static void RunOperations(TimeSpan workerOperationTimeout)
{
using (var evt = new ManualResetEvent(false))
using (var cts = new CancellationTokenSource())
{
Console.WriteLine("注册等待信号");
var worker = ThreadPool.RegisterWaitForSingleObject(evt,
(state, isTimedOut) => WorkerOperationWait(cts, isTimedOut), null, workerOperationTimeout, true);
Console.WriteLine("开始操作");
ThreadPool.QueueUserWorkItem(_ => WorkerOperation(cts.Token, evt));
Thread.Sleep(workerOperationTimeout.Add(TimeSpan.FromSeconds(2)));
worker.Unregister(evt);
}
}
static void WorkerOperation(CancellationToken token, ManualResetEvent evt)
{
for (int i = 0; i < 6; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("已经超时业务");
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
evt.Set();
}
static void WorkerOperationWait(CancellationTokenSource cts, bool isTimedOut)
{
if (isTimedOut)
{
cts.Cancel();
Console.WriteLine("超时需要取消");
}
else
{
Console.WriteLine("操作执行");
}
}
}