2013-07-12 3 views
0

Я пытаюсь иметь несколько задач, которые занимают объекты из параллельной коллекции, но только при наличии определенного ресурса.Task scheduling и WaitHandles

По причине сигнализации о наличии этого ресурса я использовал ManualResetEvent, и мое тело задачи выглядит следующим образом:

 while(!_token.IsCancellationRequested) 
     { 
      operationsLock.WaitLock(); 
      _token.ThrowIfCancellationRequested(); 
      // dothings 
     } 

Однако, я заметил, что с момента замок разблокирован к моменту, когда задачи будут перенесены, у меня может быть несколько сотен миллисекунд, где задачи могут быть перезапущены, а они нет, вероятно, потому, что они просто не запланированы.

Я начинаю задачи с TaskFactory, как я могу улучшить это поведение? Есть ли лучшая стратегия для приостановки задач, пока ресурс недоступен?

ответ

1

В этом случае использовать WaitHandle слишком дорого, потому что задача ожидания потребляет ресурсы памяти. Вы должны использовать все доступные объекты из коллекции в одной задаче, а если нет доступных элементов, задача должна быть завершена.

void ConsumingTaskBody() 
{ 
    bool available; 
    do 
    { 
     available = _collection.TryGetNext(out item); 
     Process(item); 
    }while(available); 
} 

Если новый элемент добавлен в коллекцию, вы должны проверить, если задача уже запущена, а если нет, то начните новую.

void OnNewItemAdded() 
{ 
    if(_taskRunning) 
     return; 
    StartNewConsumingTask(); 
} 

Вы можете использовать ThreadPool, не тратя ресурсы на создание новых задач.