Я использую TaskCompletionSource<>
довольно часто. У меня есть проект сетевого протокола, где я получаю много потоков в одном соединении TCP / IP. Я демультиплексирую эти потоки и затем информирую соответствующие «SubConnections» о новом контенте.
Эти «SubConnections» (ожидающие через await
) затем должны продолжить в новом потоке.
Обычно Я решаю такие проблемы, помещая вызов TaskComplectionSource<>.Set
в анонимный метод ThreadPool.QueueUserWorkItem
, например:
ThreadPool.QueueUserWorkItem(delegate { tcs.SetResult(null); });
Если я не сделаю этого, соответствующий вызов await tcs.Task
продолжится в потоке, который называется tcs.SetResult
.
Тем не менее, я знаю, что это не правильный способ делать вещи. Также можно самостоятельно написать SynchronizationContext
(или что-то в этом роде), который будет инструктировать вызов await
для продолжения в другом потоке.
Мой основной вопрос здесь: Как бы я это сделал в способ «лучшей практики»?
Я также надеюсь избежать издержек ThreadPool
, потому что он довольно высок на Linux по сравнению с простой блокировкой потока и ожиданием ManualResetEvent
- даже если SynchronizationContext
(или что-то еще) может также использовать ThreadPool
.
Пожалуйста, не говорите мне, что вообще плохая идея мультиплексировать что-то в одном соединении tcp / ip или что Я должен просто использовать System.IO.Pipelines, REST или что-то еще. Это мой сценарий. Спасибо.