Что является лучшим способом, чтобы дроссель many.NET экземпляры задачи?


Я создал большое количество экземпляров задач. Мне нужно запустить их все, и ждать, пока они все закончатся. Проблема в том, что мне нужно убедиться, что между "начатыми" и "завершенными" в любой момент времени находится не более X задач; задачи включают вызовы другим сторонам, которые имеют ограничение на количество одновременных вызовов. Поскольку эти ограничения не основаны на моем оборудовании, я не могу полагаться на любое встроенное интеллектуальное дросселирование; мне нужно строго соблюдать ограничение. Я это удалось сделать, когда задачи увеличивают и уменьшают общую переменную потокобезопасным способом, но это кажется излишне громоздким. Есть ли способ, который более встроен в API напрямую, или простой инструмент синхронизации, которого мне не хватает?

2 5

2 ответа:

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

Edit: для этого требуется больше кода, чем для семафора, но у меня есть ощущение, что это может работать лучше, потому что пул потоков, в котором выполняются задачи, не знает о вашем семафоре, но использование TaskScheduler играет по их правилам.

Edit 2: одним из возможных недостатков использования семафора является то, что пул потоков может думать, что ваша задача - выполнять операции ввода-вывода и планировать их много за один раз (чтобы они зависали и ждали, потому что им не нужен процессор). С помощью TaskScheduler они будут запланированы именно тогда, когда для них найдется место. Это определенно будет держать бассейн чище.

Класс семафора может работать для вас: http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx

Есть хороший пример на этой странице MSDN, чтобы показать вам, как его использовать.

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