ThreadPool - WaitAll 64句柄限制

时间:2010-06-30 19:18:08

标签: c# multithreading threadpool

我试图绕过.net 3.5强加的wait64句柄限制

我见过这个帖子:Workaround for the WaitHandle.WaitAll 64 handle limit?

所以我理解一般的想法,但我遇到了困难,因为我没有使用代表,而是

我基本上是这个例子的工作: http://msdn.microsoft.com/en-us/library/3dasc8as%28VS.80%29.aspx

此链接http://www.switchonthecode.com/tutorials/csharp-tutorial-using-the-threadpool 类似但是同时跟踪任务的int变量是一个成员变量。

在上面的例子中我将传递threadCount整数? 我是否将它作为对象在回调方法中传递?我认为我遇到了回调方法的麻烦并通过引用传递。

谢谢Stephen,

这个链接对我来说并不完全清楚。

让我发布我的代码以帮助自己澄清:

for (int flows = 0; flows < NumFlows; flows++)
{
ResetEvents[flows] = new ManualResetEvent(false);
ICalculator calculator = new NewtonRaphson(Perturbations);
Calculators[flows] = calculator;
ThreadPool.QueueUserWorkItem(calculator.ThreadPoolCallback, flows);
}
resetEvent.WaitOne();

我将在哪里传递threadCount变量。我假设它需要在calculator.ThreadPoolCallback中递减?

2 个答案:

答案 0 :(得分:1)

您不应该使用多个等待句柄来等待ThreadPool中多个工作项的完成。它不仅不具有可扩展性,而且最终会遇到WaitHandle.WaitAll方法强加的64个句柄限制(正如您已经做过的那样)。在这种情况下使用的正确模式是计数等待句柄。通过Reactive Extensions类在{3.5}下载.NET 3.5中提供了一个。

var finished = new CountdownEvent(1);
for (int flows = 0; flows < NumFlows; flows++) 
{ 
  finished.AddCount();
  ICalculator calculator = new NewtonRaphson(Perturbations); 
  Calculators[flows] = calculator; 
  ThreadPool.QueueUserWorkItem(
    (state) =>
    {
      try 
      { 
        calculator.ThreadPoolCallback(state); 
      }
      finally 
      { 
        finished.Signal(); 
      }
    }, flows);
} 
finished.Signal();
finished.Wait();

答案 1 :(得分:0)

匿名方法可能最简单:

int threadCount = 0;
for (int flows = 0; flows < NumFlows; flows++)
{
    ICalculator calculator = new NewtonRaphson(Perturbations);
    Calculators[flows] = calculator;

    // We're about to queue a new piece of work:
    //    make a note of the fact a new work item is starting
    Interlocked.Increment(ref threadCount);
    ThreadPool.QueueUserWorkItem(
        delegate
        {
            calculator.ThreadPoolCallback(flows);

            // We've finished this piece of work...
            if (Interlocked.Decrement(ref threadCount) == 0)
            {
                // ...and we're the last one.
                // Signal back to the main thread.
                resetEvent.Set();
            }
        }, null);
}
resetEvent.WaitOne();