SignalAndWait для контекста блокировки

У меня есть класс менеджера, который создает задачи для пула потоков, и каждый поток должен выполнять обратный вызов после их завершения.

Я использую блокировки для работы с переменными и полями, а сигналы — для связи между потоками. То, что я ищу, - это способ выхода из текущей блокировки() и атомарного ожидания сигнала, что-то вроде SignalAndWait, но для блокировок().

Код выглядит примерно так:

// ... part of the scheduler
foreach(WorkTask task in worktasks)
{
   lock(_syncObj)
   {
      new Job(task, myCallback); // creates a thread
      instanceCount++;
      while(instanceCount > _maxConcurrentTasks)
          _resetEvent.WaitOne(Timeout.Infinite);
   }
}

// .. the callback

void myCallback()
{
    lock(_syncObj)
    {
        instanceCount--;
        _resetEvent.Set();
    }
}

Проблема здесь в том, что .WaitOne() не выходит из блокировки(), поэтому любой поток, выполняющий обратный вызов, заблокируется.

Я возлагал большие надежды на WaitOne(Int32, bool exitContext), но этот контекст, похоже, касается удаленного взаимодействия и прочего, а не синхронизации.


person Mats Fredriksson    schedule 19.11.2008    source источник


Ответы (1)


Есть ли причина использовать примитивы событий, а не Monitor.Wait/Pulse/PulseAll? Monitor.Wait атомарно освобождает блокировку и ждет, повторно захватив блокировку, прежде чем она вернется. Дополнительные сведения см. в моей статье о потоках.

person Jon Skeet    schedule 19.11.2008
comment
Нет причин, кроме того, что вы не знаете о Pulse/PulseAll. Спасибо! - person Mats Fredriksson; 19.11.2008