Думаю, я опоздал на вечеринку.Я бы добавил две вещи:
- ManualResetEvent является IDisposable.Таким образом, вы должны убедиться, что он где-то утилизируется.
- Обработка ошибок - если один из запросов потерпит неудачу, он, вероятно, потерпит неудачу.Вероятно, вам следует повторить неудачные запросы.В качестве альтернативы вы можете вернуть значения, которые вы вернули, с указанием того, какие запросы были неудачными, чтобы вызывающий мог повторить запросы.
- Тайм-ауты на стороне клиента - их нет.Это не проблема, если для вас истекает время на стороне сервера, но в случае сбоя (например, из-за проблем с сетью) клиент зависнет навсегда.
Кроме того, я думаю, что на самом деле это лучший подход, чем Task Parallel Library.Я пробовал подход «Задача на запрос» до этого.Код был на самом деле более неуклюжим, и он имел тенденцию иметь lot активных потоков.Я до сих пор не проводил тщательного тестирования с вашим кодом, но, кажется, он работает лучше с первого взгляда.
Обновление
Я вложил некоторую работу в более или менее переписанный код выше.Моя перезапись удаляет все блокировки, поддерживает клиентские тайм-ауты зависших транзакций (редко, но это случается и может действительно испортить ваш день), а также некоторую логику обработки исключений.Существует полное решение с тестами на Bitbucket .Наиболее релевантный код находится в одном файле , хотя для него требуются некоторые помощники, которые находятся в других частях проекта.