线程Thread为我们同时处理多个任务提供了便利。但是问题又来了。当遇到以下问题时:
1.当程序有不确定的多个小的任务时,我们无法事先确定要定义多少个Thread。
2.当有新任务执行时,希望线程能够相应执行;当线程完成自己的任务时,能够释放相关资源并且线程数量进行相关减少。(换句话说,能够更加智能的控制线程数量)。
其实,不必担心,已经有了解决方法。即使用ThreadPool类。
先贴一个简单的例子:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadTest
{
class Program
{
static void Main(string[] args)
{
int nWorkerThreads;
int nCompletionProtThreads;
ThreadPool.GetMaxThreads(out nWorkerThreads, out nCompletionProtThreads);
Console.WriteLine(" 线程池中辅助线程的最大数目:{0};线程池中异步 I/O 线程的最大数目:{1} ", nWorkerThreads, nCompletionProtThreads);
Console.ReadLine();
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(JobForThread);// 将方法排入队列以便执行。此方法在有线程池线程变得可用时执行
}
Thread.Sleep(3000);
Console.ReadLine();
}
/// <summary>
/// 线程池中,每个线程要执行的操作
/// </summary>
/// <param name="state"></param>
static void JobForThread(object state)
{
for (int i = 1; i <= 3; i++)
{
Console.WriteLine(" 循环遍数 {0},当前托管线程的唯一标识符: {1} ", i, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
}
}
}
}
运行结果:
首先,输出了当前线程池中的可用线程的总数量,然后输出了,I/O线程的总数量。
双核系统中,默认的线程池中辅助线程的最大数目:1023;线程池中异步 I/O 线程的最大数目:1000 。
点击回车
其次,输出线程池中每个线程执行的相关任务。由于是多线程,线程采用抢占方式执行,运行的结果不会相同。
讲解:
1.ThreadPool.QueueUserWorkItem(JobForThread);该方法,的作用是:将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
这样,当线程池中,有空闲的线程时,就会执行static void JobForThread(object state); 方法。在该方法中,会循环3次,并且答应当前执行线程的ID。
2.public static bool QueueUserWorkItem(WaitCallback callBack);方法。
public static bool QueueUserWorkItem(WaitCallback callBack);
该方法作用是:将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
WaitCallback 方法的签名:
public delegate void WaitCallback(object state);
可见,从该委托的签名中,我们可以知道,该委托需要返回值为void,并且参数为object的方法。所以,我们将static void JobForThread(object state)方法赋予该委托。
注意:
1.线程池中的所有线程都是后台线程。当程序进程停止了,线程池中的所有线程也会停止。不能把线程池中的线程改变为前台线程。
2.不能给线程池中的线程设置优先级和线程名称。
3.线程池中的线程,应该执行较短小的任务。如果需要较长时间执行的任务,应该用Thread来进行。
线程池技术比较简单,您现在应该了解了吧?!
希望能为您带来帮助,谢谢!