更新:2007 年 11 月
“线程池”是可以用来在后台执行多个任务的线程集合。(有关背景信息,请参见使用线程处理(C# 编程指南)。)这使主线程可以自由地异步执行其他任务。
线程池通常用于服务器应用程序。每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会占用主线程,也不会延迟后续请求的处理。
一旦池中的某个线程完成任务,它将返回到等待线程队列中,等待被再次使用。这种重用使应用程序可以避免为每个任务创建新线程的开销。
线程池通常具有最大线程数限制。如果所有线程都繁忙,则额外的任务将放入队列中,直到有线程可用时才能够得到处理。
您可以实现自己的线程池,但是通过
下面的示例使用 .NET Framework 线程池计算 20 和 40 之间的十个数的 Fibonacci 结果。每个 Fibonacci 结果都由 Fibonacci 类表示,该类提供一种名为 ThreadPoolCallback 的方法来执行此计算。将创建表示每个 Fibonacci 值的对象,ThreadPoolCallback 方法将传递给
由于为每个 Fibonacci 对象都提供了一个半随机值来进行计算,而且每个线程都将争用处理器时间,因此无法提前知道十个结果全部计算出来所需的时间。这就是为何会在构造期间为每个 Fibonacci 对象传递
示例
C# | 复制代码 |
---|---|
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(); // Configure and launch threads using ThreadPool: 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); } // Wait for all threads in pool to calculation... 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); } } } |
输出如下:
复制代码 | |
---|---|
launching 10 tasks... result calculated... result calculated... result calculated... result calculated... result calculated... result calculated... result calculated... result calculated... result calculated... result calculated... all calculations complete Fibonacci(22) = 17711 Fibonacci(25) = 75025 Fibonacci(32) = 2178309 Fibonacci(36) = 14930352 Fibonacci(32) = 2178309 Fibonacci(26) = 121393 Fibonacci(35) = 9227465 Fibonacci(23) = 28657 Fibonacci(39) = 63245986 Fibonacci(22) = 17711 |