如何:使用线程池(C# 和 Visual Basic)
如何:使用线程池(C# 和 Visual Basic)
“线程池”是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。 有关更多信息,请参见线程池(C# 和 Visual Basic)。
下面的示例使用 .NET Framework 线程池为介于 20 和 40 之间的十个数字计算 Fibonacci 结果。 每个 Fibonacci 结果都由 Fibonacci 类表示,该类提供一个名为ThreadPoolCallback 的方法,用于执行计算。 将创建表示每个 Fibonacci 值的对象,ThreadPoolCallback 方法将传递给 QueueUserWorkItem,它分配池中的一个可用线程来执行此方法。
由于为每个 Fibonacci 对象都提供了一个半随机值来进行计算,而且每个线程都将争用处理器时间,因此无法提前知道十个结果全部计算出来所需的时间。 这就是为何会在构造期间为每个 Fibonacci 对象传递 ManualResetEvent 类的一个实例的原因。 当计算完成时,每个对象都通知提供的事件对象,使主线程用 WaitAll 阻止执行,直到十个Fibonacci 对象全部计算出了结果。 然后 Main 方法将显示每个 Fibonacci 结果。
using System; using System.Threading; public class Fibonacci { private int _n; private int _fibOfN; private ManualResetEvent _doneEvent; public int N { get { return _n; } } public int FibOfN { get { return _fibOfN; } } // Constructor. 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 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 start 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 calculate. 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... thread 0 started... thread 1 started... thread 1 result calculated... thread 2 started... thread 2 result calculated... thread 3 started... thread 3 result calculated... thread 4 started... thread 0 result calculated... thread 5 started... thread 5 result calculated... thread 6 started... thread 4 result calculated... thread 7 started... thread 6 result calculated... thread 8 started... thread 8 result calculated... thread 9 started... thread 9 result calculated... thread 7 result calculated... All calculations are complete. Fibonacci(38) = 39088169 Fibonacci(29) = 514229 Fibonacci(25) = 75025 Fibonacci(22) = 17711 Fibonacci(38) = 39088169 Fibonacci(29) = 514229 Fibonacci(29) = 514229 Fibonacci(38) = 39088169 Fibonacci(21) = 10946 Fibonacci(27) = 196418

浙公网安备 33010602011771号