Heim >Backend-Entwicklung >C++ >Wie kann ich in einer parallelen Schleife in C#asynchrone Operationen richtig warten?

Wie kann ich in einer parallelen Schleife in C#asynchrone Operationen richtig warten?

Susan Sarandon
Susan SarandonOriginal
2025-02-01 03:21:08395Durchsuche

How Can I Properly Await Asynchronous Operations within a Parallel.ForEach Loop in C#?

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.

zugreift

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn