线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
C# 中线程池 ThreadPool 的主要方法
// 参数:
// workerThreads:
// 要由线程池根据需要创建的新的最小工作程序线程数。
// completionPortThreads:
// 要由线程池根据需要创建的新的最小空闲异步 I/O 线程数。
// 返回结果:如果更改成功,则为 true;否则为 false。
[SecuritySafeCritical]
public static bool SetMinThreads(int workerThreads, int completionPortThreads);
// 参数:
// workerThreads:
// 线程池中辅助线程的最大数目。
// completionPortThreads:
// 线程池中异步 I/O 线程的最大数目。
// 返回结果:如果更改成功,则为 true;否则为 false。
[SecuritySafeCritical]
public static bool SetMaxThreads(int workerThreads, int completionPortThreads);
代码例子如下:
class Program
{
//static ManualResetEvent myEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
Console.WriteLine("主线程-Run");
ThreadPool.SetMinThreads(1, 1); // 并行线程的最小数量
ThreadPool.SetMaxThreads(2, 2); // 并行线程的最大数量
for (int i = 1; i <= 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(testFun), i.ToString());
}
Console.WriteLine("主线程-End");
//myEvent.WaitOne();
//Console.WriteLine("线程池终止!");
Console.ReadKey();
}
public static void testFun(object obj)
{
Console.WriteLine(string.Format("{0}:第{1}个线程-Run", DateTime.Now.ToString(), obj.ToString()));
Thread.Sleep(2000); // 模拟大量运算
Console.WriteLine(string.Format("{0}:第{1}个线程-End", DateTime.Now.ToString(), obj.ToString()));
//myEvent.Set();
}
}
运行结果如下:可以看出,由线程池管理的线程并没有对主线程造成影响,由于设置了并行线程的最大值为2,每次只有两个线程在工作,直到有线程结束,才会有新的线程开始工作。
线程池的缺点在于:不能获取到每一个线程,从而不能对单个线程进行操作。