等到所有线程在ThreadPool中完成工作

Nei*_*ir0 15 c# threadpool

我有这个代码:

var list = new List<int>();
for(int i=0;i<10;i++) list.Add(i); 
for(int i=0;i<10;i++)
{
     ThreadPool.QueueUserWorkItem(
         new WaitCallback(x => {
             Console.WriteLine(x);  
         }), list[i]);
} 
Run Code Online (Sandbox Code Playgroud)

我想知道所有线程池线程什么时候完成他们的工作.我该怎么做?

Ree*_*sey 25

您需要自己跟踪.

一个选项是使用计数器和重置事件:

int toProcess = 10;
using(ManualResetEvent resetEvent = new ManualResetEvent(false))
{
    var list = new List<int>();
    for(int i=0;i<10;i++) list.Add(i); 
    for(int i=0;i<10;i++)
    {
        ThreadPool.QueueUserWorkItem(
           new WaitCallback(x => {
              Console.WriteLine(x);  
              // Safely decrement the counter
              if (Interlocked.Decrement(ref toProcess)==0)
                 resetEvent.Set();

           }),list[i]);
    } 

    resetEvent.WaitOne();
}
// When the code reaches here, the 10 threads will be done
Console.WriteLine("Done");
Run Code Online (Sandbox Code Playgroud)

  • @ Neir0:由于许多线程可能会同时执行此操作,因此您需要保护该减量.有两种选择 - 使用Interlocked,或使用某种形式的锁定.如果您只使用--toProcess,并且两个线程尝试在同一时间执行它,则您将永远不会达到零. (5认同)

moo*_*aka 16

在.NET Framework 4+中使用方便的System.Threading.CountdownEvent类:

const int threadCount = 10;
var list = new List<int>(threadCount);
for (var i = 0; i < threadCount; i++) list.Add(i);

using (var countdownEvent = new CountdownEvent(threadCount))
{
    for (var i = 0; i < threadCount; i++)
        ThreadPool.QueueUserWorkItem(
            x =>
            {
                Console.WriteLine(x);
                countdownEvent.Signal();
            }, list[i]);

    countdownEvent.Wait();
}
Console.WriteLine("done");
Run Code Online (Sandbox Code Playgroud)


Dar*_*rov 9

我不确定ThreadPool是否公开了这样的功能但你可以使用等待句柄,顺便说两次迭代似乎是不必要的:

var events = new ManualResetEvent[10];
var list = new List<int>();
for (int i = 0; i < 10; i++)
{
    list.Add(i);
    events[i] = new ManualResetEvent(false);
    int j = i;
    ThreadPool.QueueUserWorkItem(x => {
        Console.WriteLine(x);
        events[j].Set();
    }, list[i]);
}
WaitHandle.WaitAll(events);
Run Code Online (Sandbox Code Playgroud)

  • 只是警告这个......如果STA线程中有超过64个项目,WaitHandle.WaitAll将失败... (8认同)
  • 为什么在只需要1时创建10个事件? (2认同)