Получение 2 -го `iAsyncenumerator <>` из того же `jasyncenumerable <>` на основе `task.wheneach <>` methodC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Получение 2 -го `iAsyncenumerator <>` из того же `jasyncenumerable <>` на основе `task.wheneach <>` method

Сообщение Anonymous »

Учитывая one iAsyncenumerable , в целом он работает нормально (даже если это может быть неоптимальным с точки зрения производительности), чтобы вызвать getAsyncenumerator более одного раза, получая < em> new iasyncenumerator каждый раз. Чтобы привести явный пример (весь код в этом вопросе находится в C#), предположим, что у меня есть этот метод: < /p>

Код: Выделить всё

static async IAsyncEnumerable GetStr() {
var item = await Task.FromResult("Bravo");
yield return "Alfa";
yield return item;
yield return "Charlie";
}
< /code>
Тогда он работает нормально, чтобы сделать это: < /p>
IAsyncEnumerable oneEnumerable = GetStr();
await foreach (var s in oneEnumerable) {
Console.WriteLine(s);
}
Console.WriteLine("Between");
await foreach (var t in oneEnumerable) {
Console.WriteLine(t);
}
Console.WriteLine("End");
Если вы хотите быть продвинутыми, у вас даже может быть два перечисления (из одного и того же перечисленного) в прямом эфире, без утилизации первого, прежде чем приобрести второй, скажем:

Код: Выделить всё

IAsyncEnumerable oneEnumerable = GetStr();
IAsyncEnumerator e = oneEnumerable.GetAsyncEnumerator();
IAsyncEnumerator f = oneEnumerable.GetAsyncEnumerator();
bool c = await f.MoveNextAsync();
bool b = await e.MoveNextAsync();

Console.WriteLine($"b {b} with {e.Current}");
Console.WriteLine($"c {c} with {f.Current}");
await e.DisposeAsync();
await f.DisposeAsync();
< /code>
Приведенный выше код работает так, как вы, ребята, ожидаете, два перечисления являются независимыми и не смешивают их состояния. < /p>

Так что это было просто введение; Я хочу спросить о случае, когда приобретение двух перечислений из одного и того же перечисленного приводит к странному результату. Итак, теперь рассмотрим этот метод на основе задачи.static IAsyncEnumerable GetTasks() {
IEnumerable source = [Task.FromResult(7), Task.FromResult(9), Task.FromResult(13)];
return Task.WhenEach(source);
}
< /code>
и используйте этот код: < /p>
IAsyncEnumerable oneEnumerable = GetTasks();
await foreach (var t in oneEnumerable) {
Console.WriteLine(t);
}
Console.WriteLine("Between");
await foreach (var u in oneEnumerable) {
Console.WriteLine(u);
}
Console.WriteLine("End");
< /code>
Это работает без исключения.  Но: второе перечисление дает нулевые элементы (тело Foreach с u < /code> запускается в нулевое время)! < /strong> < /p>

my Вопросы: < /p>

 Это ожидаемое поведение task.wheneach < /code>? < /li>
 Это поведение задокументировано? < /li>
< /ul>
Я нахожу это очень подверженным ошибкам. Если по какой -то технической причине невозможно получить более одного перечисления от перечисления, было бы гораздо приятнее, если бы второй вызов GetAsyncenumerator 
сделает исключение (или, альтернативно, первый вызов Movenextasync во втором перечислении бросил бы, или, ожидая aluetask , созданный Movenextasync . IAsyncenumerable , созданный GetRecordSasync a CSVreader имел аналогичную проблему.)


Подробнее здесь: https://stackoverflow.com/questions/794 ... e-based-on
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»