Erhalten Sie einen 2. `iAsyncenumerator <>` aus derselben `iAsyncenumerable <>` basierend auf `task.wheach <>`C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Erhalten Sie einen 2. `iAsyncenumerator <>` aus derselben `iAsyncenumerable <>` basierend auf `task.wheach <>`

Post by Anonymous »

gegeben Ein iayncenumerable funktioniert es im Allgemeinen gut (auch wenn es nicht optimal leistungsstark sein kann), GetAsyncenumerator mehr als einmal aufzurufen, wobei er ein neu iAsyncenumerator Jedes Mal. Um ein explizites Beispiel zu geben (der gesamte Code in dieser Frage ist in C#), nehmen Sie an, dass ich diese Methode habe: < /p>

Code: Select all

static async IAsyncEnumerable GetStr() {
var item = await Task.FromResult("Bravo");
yield return "Alfa";
yield return item;
yield return "Charlie";
}
< /code>
Dann funktioniert es gut, dies zu tun: < /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");
Wenn Sie erweitert werden möchten, können Sie sogar die beiden Aufzähler (von derselben Aufzählung) zusammenleben lassen, ohne die Ersten zu entsorgen, bevor Sie den zweiten erwerben, sagen wir:

Code: Select all

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>
Der obige Code funktioniert so, wie Sie es erwarten, die beiden Enzeratoren sind unabhängig und mischen ihre Zustände nicht. < /p>

Das war also nur eine Einführung; Ich möchte nach einem Fall fragen, in dem der Erwerb von zwei Aufzählern aus demselben aufzählbaren Ergebnis zu einem seltsamen Ergebnis führt. Betrachten Sie nun diese Methode basierend auf Task.wheneach: < /p>
static IAsyncEnumerable GetTasks() {
IEnumerable source = [Task.FromResult(7), Task.FromResult(9), Task.FromResult(13)];
return Task.WhenEach(source);
}
< /code>
und verwenden Sie diesen 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>
Dies wird ausnahmslos ausgeführt.  Aber: Die zweiten Aufzählung ergibt Nullelemente (Körperschaft mit u < /code> läuft null mal)! < /strong> < /p>

Mein Fragen: < /p>

 Ist dies das erwartete Verhalten der Aufgabe? < /li>
< /ul>
Ich finde es sehr fehleranfällig. Wenn es aus irgendeinem technischen Grund unmöglich ist, mehr als eine Aufzählung von einem aufzählbaren Aufzählungszusammenhang zu erhalten, wäre es viel schöner, wenn der zweite Aufruf von Getasyncenumerator 
eine Ausnahme (oder alternativ den ersten Anruf an MovextenextAsync Auf dem zweiten Enumerator würde das Valuetask erwarten oder von MoveExtextAsync erzeugt). Ein iAsyncenumerable wurde von GetRecordsAsync eines csvReader ein ähnliches Problem.)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post