Heim >Backend-Entwicklung >C++ >Wie kann ich in einer parallelen Schleife in C#asynchrone Operationen richtig warten?
Parallele asynchrone Operationen mit Parallel.ForEach
in C#
Die Verbesserung der Anwendungsleistung beinhaltet häufig eine parallele Verarbeitung. Die Kombination von asynchronen Operationen (async
/await
) mit parallelen Schleifen wie Parallel.ForEach
ist jedoch einzigartige Herausforderungen. Dieser Artikel befasst sich mit diesen Herausforderungen und liefert Lösungen für die korrekte Wartezeit von asynchronen Aufgaben innerhalb einer parallelen Schleife.
Das Problem: Asynchrone Aufgaben und Parallel.ForEach
Das Schlüsselwort async
in C# ermöglicht eine asynchrone Programmierung, wobei ein Task
-Objekt zurückgegeben wird. Das Problem tritt auf, wenn async
Methoden innerhalb von Parallel.ForEach
verwendet werden, da Hintergrund -Threads nicht von Natur aus warten, bis asynchrone Aufgaben abgeschlossen sind, bevor die Schleife abgeschlossen ist.
Betrachten Sie dieses Beispiel:
<code class="language-csharp">var bag = new ConcurrentBag<object>(); Parallel.ForEach(myCollection, async item => { // Pre-processing var response = await GetData(item); bag.Add(response); // Post-processing }); var count = bag.Count; // count is often 0!</code>
count
Gibt häufig 0 zurück, da der Haupt -Thread fortgesetzt wird, bevor die Hintergrund -Threads ihre asynchronen Operationen abschließen.
Lösung: Verwenden Sie Select
und Task.WhenAll
Eine robuste Lösung beinhaltet Select
, um eine Sammlung von Task
Objekten und Task.WhenAll
zu erstellen, um auf alle Aufgaben zu warten:
<code class="language-csharp">var bag = new ConcurrentBag<object>(); var tasks = myCollection.Select(async item => { // Pre-processing var response = await GetData(item); bag.Add(response); // Post-processing }); await Task.WhenAll(tasks); var count = bag.Count; // count will be correct</code>
Dieser Ansatz initiiert asynchrone Operationen gleichzeitig mit Select
und verwendet dann Task.WhenAll
, um alle Aufgaben abzuschließen, bevor er auf die bag
.
Erweiterte Lösungen: ForEachAsync
Für kompliziertere Szenarien bietet Stephen Toubs Blog -Beitrag über ForEachAsync
eine anspruchsvollere und anpassungsfähigere Lösung:
https://www.php.cn/link/33edf41c0becd0d57c35c4e27276617b
Dies bietet eine kontrolliertere und effizientere Methode zum Umgang mit parallele asynchronen Operationen, insbesondere bei potenziellen Ausnahmen oder Stornierung. Es bietet einen robusteren und flexibleren Ansatz im Vergleich zur einfachen Select
/Task.WhenAll
-Methode.
Das obige ist der detaillierte Inhalt vonWie kann ich in einer parallelen Schleife in C#asynchrone Operationen richtig warten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!