C#多线程之 线程池 ThreadPool介绍

背景

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"); 

你可能感兴趣的:(C#高级编程)