怎样使用C#中的线程池

来源:互联网 发布:mac候选字窗口消失 编辑:程序博客网 时间:2024/06/05 09:10
(原文来自http://msdn2.microsoft.com/en-us/library/3dasc8as.aspx 微软MSDN社区,原文为英文)
一个线程池是一个可以完成一系列当前环境下任务的线程的集合,他能够释放主线程去执行新的异步任务
 
线程池常常被用在服务器的应用程序上,每一个进入的请求被分配给线程池中的一个线程,所以每个请求可以被异步的处理而不用绑定到主线程或者延迟后续的请求处理
 
一旦线程池中的一个线程完成了任务就会马上返回到等待线程的队列中,在这里线程可以被复用。这种复用能够避免应用程序创建新的线程的额外开销
 
线程池特别的有个线程的最大值,如果所有的线程都是忙碌的。附加的任务会被放置到队列中知道有线程完成任务可以来执行这些任务
 
你可以实现你自己的线程池,但是使用.net framework提供的ThreadPool Class会更加简单
 
下面的是一个利用.NET Framework threadPool计算费波拉契数列的例子,每个费波拉契的结果被一个费波拉契的类所表示,这个类提供了一个方法——ThreadPoolCallBack,这个方法用来执行计算操作,一个object代表每个费波拉契对象的值被创建。这个方法被传递到ThreadPool的QueueUserWorkItem中,这个方法用来分配可用的线程来执行方法
 
因为每个费波拉契对象被赋予一个随机数来计算结果,而且10个线程都在争用CPU时间,所以我们没有办法事先知道完成所有10个线程所要花费的时间。这就是为什么每个费波拉契对象在构造函数中都会分配一个ManualResetEvent对象,用来标志计算完成,这个对象用来让主线程使用WaiAll方法阻塞操作直到所有10个线程都完成计算。然后由主线程显示结果 
 
using System;using System.Threading;public class Fibonacci{    public Fibonacci(int n, ManualResetEvent doneEvent)    {        _n = n;        _doneEvent = doneEvent;    }    // Wrapper method for use with thread pool.    public void ThreadPoolCallback(Object threadContext)    {        int threadIndex = (int)threadContext;        Console.WriteLine("thread {0} started...", threadIndex);        _fibOfN = Calculate(_n);        Console.WriteLine("thread {0} result calculated...", threadIndex);        _doneEvent.Set();    }    // Recursive method that calculates the Nth Fibonacci number.    public int Calculate(int n)    {        if (n <= 1)        {            return n;        }        return Calculate(n - 1) + Calculate(n - 2);    }    public int N { get { return _n; } }    private int _n;    public int FibOfN { get { return _fibOfN; } }    private int _fibOfN;    private ManualResetEvent _doneEvent;}public class ThreadPoolExample{    static void Main()    {        const int FibonacciCalculations = 10;        // One event is used for each Fibonacci object        ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];        Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];        Random r = new Random();        // 开始使用线程池        Console.WriteLine("launching {0} tasks...", FibonacciCalculations);        for (int i = 0; i < FibonacciCalculations; i++)        {            doneEvents[i] = new ManualResetEvent(false);            Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);            fibArray[i] = f;            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);        }        // 等待线程池中所有计算完成        WaitHandle.WaitAll(doneEvents);        Console.WriteLine("All calculations are complete.");        // Display the results...        for (int i = 0; i < FibonacciCalculations; i++)        {            Fibonacci f = fibArray[i];            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);        }    }}