线程池 - WaitAll 64 句柄限制

发布于 2024-09-07 12:58:28 字数 1198 浏览 1 评论 0原文

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

我看到了这个线程: WaitHandle.WaitAll 64 句柄限制的解决方法?

所以我理解总体思路,但我遇到了困难,因为我没有使用委托,而是

基本上正在处理这个示例: http://msdn.microsoft.com/en- us/library/3dasc8as%28VS.80%29.aspx

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

在上面的示例中,我将在哪里传递 threadCount 整数? 我是否将其作为对象传递到回调方法中?我认为我在回调方法和通过引用传递方面遇到了问题。

谢谢斯蒂芬,

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

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

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中递减?

I am trying to bypass the the wait64 handle limit that .net 3.5 imposes

I have seen this thread : Workaround for the WaitHandle.WaitAll 64 handle limit?

So I understand the general idea but I am having difficulty because I am not using a delegate but rather

I am basically working of this example :
http://msdn.microsoft.com/en-us/library/3dasc8as%28VS.80%29.aspx

This link http://www.switchonthecode.com/tutorials/csharp-tutorial-using-the-threadpool
is similar but again the int variable keeping track of the tasks is a member variable.

Where in the above example would I pass the threadCount integer?
Do I pass it in the callback method as an object? I think I am having trouble with the callback method and passing by reference.

Thanks Stephen,

That link is not entirely clear to me.

Let me post my code to help myself clarify:

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();

Where would I pass in my threadCount variable. I assume it needs to be decremented in calculator.ThreadPoolCallback?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清引 2024-09-14 12:58:28

您不应使用多个等待句柄来等待ThreadPool 中多个工作项的完成。它不仅不可扩展,您最终还会遇到 WaitHandle.WaitAll 方法施加的 64 个句柄限制(正如您已经完成的那样)。在这种情况下使用的正确模式是计数等待句柄。在 .NET 3.5 的响应式扩展下载中可以通过CountdownEvent 类。

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();

You should not be using multiple wait handles to wait for the completion of multiple work items in the ThreadPool. Not only is it not scalable you will eventually bump into the 64 handle limit imposed by the WaitHandle.WaitAll method (as you have done already). The correct pattern to use in this situation is a counting wait handle. There is one available in the Reactive Extensions download for .NET 3.5 via the CountdownEvent class.

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();
围归者 2024-09-14 12:58:28

匿名方法可能是最简单的:

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();

An anonymous method might be easiest:

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文