2010-06-30 30 views
2

我試圖繞過的wait64句柄限制是.NET 3.5的規定線程池 - 爲WaitAll 64句柄限制

我已經看到了這個線程: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整數嗎? 作爲對象在回調方法中傳遞它嗎?我認爲我遇到了回調方法和參考傳遞的問題。

謝謝斯蒂芬,

該鏈接是不完全清楚的我。

讓我後我的代碼,以幫助自己澄清:

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中遞減?

+0

什麼是numTask整數? – 2010-06-30 19:22:05

+0

對不起,我相信我的意思是來自第一個鏈接的「threadCount」。 – bearrito 2010-06-30 19:31:45

+1

次要技術問題:64句柄限制是由Win32 API而不是.NET 3.5強加的。所以,Windows上的每個程序都有相同的限制。 – 2010-06-30 19:34:17

回答

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

如果你看看提供的鏈接,你可以看到我試圖避免使用匿名方法。 – bearrito 2010-07-02 18:04:08

+0

我不明白你爲什麼要避免匿名方法 - 你的目標是.NET 1.0或1.1運行時? – 2010-07-02 18:26:12

+0

這裏有一個非常微妙的錯誤。 'WaitOne'和'Interlocked.Decrement'將會競爭導致'WaitOne'返回太早,如果最後一個工作項已經排隊*和*在循環的下一次迭代有機會'Interlocked.Increment'之前完成。 – 2010-10-01 17:20:39

1

你不應該使用多個等待句柄等待在ThreadPool多個工作項目的完成。它不僅不可擴展,而且最終還會碰到WaitHandle.WaitAll方法施加的64個句柄限制(正如您已經完成的那樣)。在這種情況下使用的正確模式是計數等待句柄。有一個可用的Reactive Extensions下載的.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();