C# · 12月 21, 2021

[C#]如何使用ThreadPool

摘要<p style="margin-left: 30px;">线程池是一种多线程的形式,其中的任务被添加到队列中,并在创建线程时自动启动。

<p style="margin-left: 30px;">以下示例使用.Net框架的线程池来计算十个数字20和40之间的裴波那契的结果。裴波那契Fibonacci类,它提供了一种方法叫ThreadPoolCallback执行计算。一个对象表示一个裴波那契的值被创建,ThreadPoolCallback方法是通过queueuserworkitem分配可能的线程池中执行的方法。

<p style="margin-left: 30px;">因为每个裴波那契对象提供一个半随机值来计算,因为每个线程将竞争处理器时间,你不能提前知道多久将采取所有是个结果来计算。这就是为什么每个裴波那契对象传递的manualresetevent类的一个实例在施工。每个对象的信号提供的事件对象计算完成,这使主线程阻止执行waitall直到所有的裴波那契对象计算结果。然后main函数显示结果。

一个例子<span style=”color: #0000ff;”>namespace<span style=”color: #000000;”> ThreadPoolDemo
{
<span style=”color: #0000ff;”>class<span style=”color: #000000;”> Program
{
<span style=”color: #0000ff;”>static <span style=”color: #0000ff;”>void Main(<span style=”color: #0000ff;”>string<span style=”color: #000000;”>[] args)
{
<span style=”color: #0000ff;”>const <span style=”color: #0000ff;”>int FibonacciCalculations = <span style=”color: #800080;”>10<span style=”color: #000000;”>;
ManualResetEvent[] doneEvents = <span style=”color: #0000ff;”>new<span style=”color: #000000;”> ManualResetEvent[FibonacciCalculations];
Fibonacci[] fibArray = <span style=”color: #0000ff;”>new<span style=”color: #000000;”> Fibonacci[FibonacciCalculations];
Random r = <span style=”color: #0000ff;”>new<span style=”color: #000000;”> Random();
Console.WriteLine(<span style=”color: #800000;”>”<span style=”color: #800000;”>launching {0} tasks…<span style=”color: #800000;”>”<span style=”color: #000000;”>,FibonacciCalculations);
<span style=”color: #0000ff;”>for (<span style=”color: #0000ff;”>int i = <span style=”color: #800080;”>0; i < FibonacciCalculations; i++<span style=”color: #000000;”>)
{
doneEvents[i] = <span style=”color: #0000ff;”>new ManualResetEvent(<span style=”color: #0000ff;”>false<span style=”color: #000000;”>);
Fibonacci f = <span style=”color: #0000ff;”>new Fibonacci(r.Next(<span style=”color: #800080;”>20,<span style=”color: #800080;”>40<span style=”color: #000000;”>),doneEvents[i]);
fibArray[i] =<span style=”color: #000000;”> f;
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback,i);
}
<span style=”color: #008000;”>//<span style=”color: #008000;”>wait for all threads in pool to calculate
<span style=”color: #000000;”> WaitHandle.WaitAll(doneEvents);
<span style=”color: #0000ff;”>for (<span style=”color: #0000ff;”>int i = <span style=”color: #800080;”>0; i < FibonacciCalculations; i++<span style=”color: #000000;”>)
{
Fibonacci f =<span style=”color: #000000;”> fibArray[i];
Console.WriteLine(<span style=”color: #800000;”>”<span style=”color: #800000;”>Fibonacci({0})={1}<span style=”color: #800000;”>”<span style=”color: #000000;”>,f.N,f.FibofN);
}
Console.Read();
}
}
<span style=”color: #0000ff;”>public <span style=”color: #0000ff;”>class<span style=”color: #000000;”> Fibonacci
{
<span style=”color: #0000ff;”>private <span style=”color: #0000ff;”>int<span style=”color: #000000;”> _n;
<span style=”color: #0000ff;”>private <span style=”color: #0000ff;”>int<span style=”color: #000000;”> _fibofN;
<span style=”color: #0000ff;”>private<span style=”color: #000000;”> ManualResetEvent _doneEvent;
<span style=”color: #0000ff;”>public <span style=”color: #0000ff;”>int N { <span style=”color: #0000ff;”>get { <span style=”color: #0000ff;”>return<span style=”color: #000000;”> _n; } }
<span style=”color: #0000ff;”>public <span style=”color: #0000ff;”>int FibofN { <span style=”color: #0000ff;”>get { <span style=”color: #0000ff;”>return<span style=”color: #000000;”> _fibofN; } }
<span style=”color: #0000ff;”>public Fibonacci(<span style=”color: #0000ff;”>int<span style=”color: #000000;”> n,ManualResetEvent doneEvent)
{
_n =<span style=”color: #000000;”> n;
_doneEvent =<span style=”color: #000000;”> doneEvent;
}
<span style=”color: #0000ff;”>public <span style=”color: #0000ff;”>void ThreadPoolCallback(<span style=”color: #0000ff;”>object<span style=”color: #000000;”> threadContext)
{
<span style=”color: #0000ff;”>int threadIndex = (<span style=”color: #0000ff;”>int<span style=”color: #000000;”>)threadContext;
Console.WriteLine(<span style=”color: #800000;”>”<span style=”color: #800000;”>thread {0} started….<span style=”color: #800000;”>”<span style=”color: #000000;”>,threadIndex);
_fibofN =<span style=”color: #000000;”> Calculate(_n);
Console.WriteLine(<span style=”color: #800000;”>”<span style=”color: #800000;”>thread {0} result calculated…<span style=”color: #800000;”>”<span style=”color: #000000;”>,threadIndex);
_doneEvent.Set();
}
<span style=”color: #0000ff;”>public <span style=”color: #0000ff;”>int Calculate(<span style=”color: #0000ff;”>int<span style=”color: #000000;”> n)
{
<span style=”color: #0000ff;”>if (n <= <span style=”color: #800080;”>1<span style=”color: #000000;”>)
{
<span style=”color: #0000ff;”>return<span style=”color: #000000;”> n;
}
<span style=”color: #0000ff;”>return Calculate(n – <span style=”color: #800080;”>1) + Calculate(n – <span style=”color: #800080;”>2<span style=”color: #000000;”>);
}
}
}

<p style="margin-left: 30px;">结果

<p style="margin-left: 30px;">

<p style="margin-left: 30px;">参考

<p style="margin-left: 30px;">