Сочетание ручек ожидания? - PullRequest
4 голосов
/ 31 декабря 2010

Немного интересного здесь, я думаю.У меня есть класс, который отвечает за «мультиплексирование» нескольких операций обработки на фиксированное количество потоков.Типичным случаем является своего рода проблема производителя / потребителя, где каждая операция состоит из WaitHandle (в данном случае, семафора, который отслеживает, сколько элементов находится в очереди) и делегата для вызова.

Например,, Если у меня есть два производителя (A и B), производящих элементы в две отдельные очереди.Вместо того, чтобы создавать два потока потребителей для каждого производителя (A1, A2, B1, B2), я мультиплексирую «потоки» четырех потребителей на два потока.Код для этого «мультиплексора» работает примерно так (немного упрощенно):

WaitHandle[] waitHandles = new WaitHandle[2];
waitHandles[0] = NumberOfItemsFullInProducerAQueue;
waitHandles[1] = NumberOfItemsFullInProducerBQueue;
while(true)
{
    int index = WaitHandle.WaitAny(waitHandles);
    if(index == 0)
    {
        // handle the item from queue A
    }
    else
    {
        // handle the item from queue B
    }
}

Я пытаюсь расширить эту концепцию на несколько более сложный пример, где для действия может потребоваться несколько дескрипторов ожидания, чтобыбыть довольным, прежде чем он будет выполнен.Мне интересно, есть ли какой-нибудь вызов WaitHandle.Combine (waitHandle1, waitHandle2), который я могу сделать, чтобы объединить два маркера ожидания в один дескриптор ожидания.Конечный результат будет выглядеть примерно так:

A,B,C,D are waitHandles
E = Combine(A, B)
F = Combine(C, D)
waitHandles = { E, F }

while(true)
{
   int index = WaitHandle.WaitAny(waitHandles);
   if(index == 0)
   {
   }
   else
   {
   }
}

Дополнительные очки?

Хотя это и не является обязательным требованием, было бы также неплохо, если бы комбинации ручек ожидания моглипересекаются.Например, что-то вроде этого:

  A,B,C are waitHandles
  D = Combine(A, B)
  E = Combine(A, C)
  waitHandles = { D, E }
  // same as above from here

Спасибо за помощь, SO

1 Ответ

1 голос
/ 31 декабря 2010

Возможно, вы захотите посмотреть на новый класс Barrier в .NET 4 TPL (с портированием на 3,5 как часть Reactive Extensions . Он специально разработан для описанных вами сценариев , где вам нужно блокировать выполнение до тех пор, пока несколько взаимодействующих задач не достигнут контрольной точки. Вы также можете использовать систему задач для создания сложных путей продолжения, при этом одна задача зависит от двух предшествующих завершений, в зависимости от завершения первой задачи и, если исключения возникают при в любой точке, когда эти исключения собраны и представлены в центральном местоположении.

...