线程池ThreadPool类
创建线程需要时间。 如果有不同的小任务要完成,就可以事先创建许多线程 , 在应完成这些任务时发出请求。 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少。
不需要自己创建线程池,系统已经有一个ThreadPool类管理线程。 这个类会在需要时增减池中线程的线程数,直到达到最大的线程数。 池中的最大线程数是可配置的。 在双核 CPU中 ,默认设置为1023个工作线程和 1000个 I/o线程。也可以指定在创建线程池时应立即启动的最小线程数,以及线程池中可用的最大线程数。 如果有更多的作业要处理,线程池中线程的个数也到了极限,最新的作业就要排队,且必须等待线程完成其任务。
线程池示例
class MainClass
{
static void ThreadMethod(object state) {
Console.WriteLine ("线程开始");
Console.WriteLine (Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("线程结束");
}
public static void Main (string[] args)
{
ThreadPool.QueueUserWorkItem (ThreadMethod);
ThreadPool.QueueUserWorkItem (ThreadMethod);
ThreadPool.QueueUserWorkItem (ThreadMethod);
ThreadPool.QueueUserWorkItem (ThreadMethod);
ThreadPool.QueueUserWorkItem (ThreadMethod);
ThreadPool.QueueUserWorkItem (ThreadMethod);
Console.ReadKey ();
}
}
static void Main(){
int nWorkerThreads;
int nCompletionPortThreads;
ThreadPool.GetMaxThreads(out nWorkerThreads,out nCompletionPortThreads);
Console.WriteLine("Max worker threads : " +nWorkerThreads+" I/O completion threads :"+nCompletionPortThreads );
for(int i=0;i<5;i++){
ThreadPool.QueueUserWorkItem(JobForAThread);
}
Thread.Sleep(3000);
}
static void JobForAThread(object state){
for(int i=0;i<3;i++){
Console.WriteLine("Loop "+i+" ,running in pooled thread "+Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(50);
}
}
示例应用程序首先要读取工作线程和 I/o线程的最大线程数,把这些信息写入控制台中。接着在 for循 环中,调 用ThreadPool.QueueUserWorkItem方法,传递一个WaitCallBack类型的委托 ,把 JobForAThread方 法赋予线程池中的线程。 线程池收到这个请求后,就会从池中选择一个线程 来调用该方法。 如果线程池还没有运行,就会创建一个线程池,并启动第一个线程。 如果线程池己经在运行,且有一个空闲线程来完成该任务,就把该作业传递给这个线程。
使用线程池需要注意的事项:
- 线程池中的所有线程都是后台线程 。 如果进程的所有前台线程都结束了,所有的后台线程就会停止。 不能把入池的线程改为前台线程 。
- 不能给入池的线程设置优先级或名称。
- 入池的线程只能用于时间较短的任务。 如果线程要一直运行(如 Word的拼写检查器线程),就应使用Thread类创建一个线程。