Я пытаюсь сделать много асинхронной работы в определенном порядке (FIFO).
Здесь код:
foreach (var header in headers)
_broker.SendAsync(header.request)
.ContinueWith(t => _broker2.SendAsync(t.Result.request2));
Проблема, с которой я сталкиваюсь, заключается в том, что продолжение не происходит до тех пор, пока все _broker.SendAsync не будут завершены. Я бы хотел, чтобы он работал более последовательно, чтобы запустить ContinueWith, как только любой из брокеров завершил отправку.
Имеет ли это смысл?
Как всегда, я предлагаю вам использовать TPL Dataflow
. Он позволяет вам объявить четкий последовательный поток и позволить TPL
обрабатывать все подробные детали позади. Вы можете настроить степень параллелизма и ограниченные возможности, чтобы сделать его более надежным.
var first = new TransformBlock<T, U>(header => _broker.SendAsync(header.request));
var second = new ActionBlock<U>(result => _broker2.SendAsync(result.request2));
first.LinkTo(second);
foreach (var header in headers)
await first.SendAsync();
ContinueWith
запускается, как только антецедент готов. В вашем коде нет ничего принудительного выполнения. На самом деле, как TPL может знать, что он вызывается из цикла foreach
и замедляет выполнение? Он не знает.
Возможно, вы неверно истолковываете то, что видите. Может быть, broker2
внутренне принуждает к серийному исполнению? Невозможно рассказать без дополнительной информации.
Рассмотрим перемещение тела цикла в вспомогательную функцию и использование async/await
there. Легче использовать.
_broker
?_broker
ли тип_broker
несколько вызовов.SendAsync
?