Короткая версия - нет, это невозможно через блок итератора; более длинная версия, вероятно, включает синхронизированную очередь / очередь между потоком итератора вызывающей стороны (выполнение очереди) и параллельными рабочими (выполнение очереди); но, как примечание: журналы обычно связаны с IO, а распараллеливание вещей, связанных с IO, часто не очень хорошо работает.
Если вызывающему абоненту потребуется некоторое время, чтобы потреблять каждый, тогда может быть некоторая заслуга в подходе, который обрабатывает только один журнал за раз, но может сделать это при вызывающий абонент использует предыдущий журнал; то есть он начинается a Task
для следующего элемента до yield
и ожидает завершения после yield
... но это опять-таки довольно сложно. В качестве упрощенного примера:
static void Main()
{
foreach(string s in Get())
{
Console.WriteLine(s);
}
}
static IEnumerable<string> Get() {
var source = new[] {1, 2, 3, 4, 5};
Task<string> outstandingItem = null;
Func<object, string> transform = x => ProcessItem((int) x);
foreach(var item in source)
{
var tmp = outstandingItem;
// note: passed in as "state", not captured, so not a foreach/capture bug
outstandingItem = new Task<string>(transform, item);
outstandingItem.Start();
if (tmp != null) yield return tmp.Result;
}
if (outstandingItem != null) yield return outstandingItem.Result;
}
static string ProcessItem(int i)
{
return i.ToString();
}