ThreadPool - предел обработки WaitAll 64 - PullRequest
2 голосов
/ 30 июня 2010

Я пытаюсь обойти ограничение дескриптора wait64, которое налагает .net 3.5

Я видел этот поток: Временное решение для ограничения дескриптора 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. Я предполагаю, что это должно быть уменьшено в калькуляторе. ThreadPoolCallback?

Ответы [ 2 ]

1 голос
/ 01 октября 2010

Вы не должны использовать несколько дескрипторов ожидания для ожидания завершения нескольких рабочих элементов в ThreadPool.Мало того, что он не масштабируется, вы в конечном итоге столкнетесь с лимитом дескриптора 64, установленным методом WaitHandle.WaitAll (как вы уже сделали).Правильный шаблон для использования в этой ситуации - дескриптор ожидания подсчета.В 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();
0 голосов
/ 01 июля 2010

Анонимный метод может быть самым простым:

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