Ich möchte eine Sammlung parallel bearbeiten, habe jedoch Probleme bei der Implementierung und hoffe daher auf Hilfe.
Das Problem tritt auf, wenn ich eine in C # als asynchron gekennzeichnete Methode innerhalb des Lambda der Parallelschleife aufrufen möchte. Beispielsweise:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
// some pre stuff
var response = await GetData(item);
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Das Problem tritt auf, wenn die Anzahl 0 ist, da alle erstellten Threads praktisch nur Hintergrund-Threads sind und der Parallel.ForEach
Aufruf nicht auf den Abschluss wartet. Wenn ich das asynchrone Schlüsselwort entferne, sieht die Methode folgendermaßen aus:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
// some pre stuff
var responseTask = await GetData(item);
responseTask.Wait();
var response = responseTask.Result;
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Es funktioniert, aber es deaktiviert die erwartete Klugheit vollständig und ich muss einige manuelle Ausnahmebehandlungen durchführen. (Der Kürze halber entfernt).
Wie kann ich eine Parallel.ForEach
Schleife implementieren , die das Schlüsselwort await im Lambda verwendet? Ist es möglich?
Der Prototyp der Parallel.ForEach-Methode verwendet einen Action<T>
as-Parameter, möchte jedoch, dass er auf mein asynchrones Lambda wartet.
await
ausawait GetData(item)
in Ihrem zweiten Codeblock als würde es einen Übersetzungsfehler erzeugen , wie sie ist.Antworten:
Wenn Sie nur einfache Parallelität wünschen, können Sie dies tun:
Wenn Sie etwas Komplexeres benötigen, lesen Sie den
ForEachAsync
Beitrag von Stephen Toub .quelle
dop
Aufgaben erstellt, und jede von ihnen verarbeitet dann eine Teilmenge der Eingabesammlung in Reihe.Task.Run
ohneawait
das Ergebnis zu erhalten, dann wirft das nur Feuer-und-Vergessen-Arbeit auf den Thread-Pool. Das ist fast immer ein Fehler.Sie können die
ParallelForEachAsync
Erweiterungsmethode aus dem AsyncEnumerator NuGet-Paket verwenden :quelle
maxDegreeOfParallelism
>maxDegreeOfParalellism
Mit können
SemaphoreSlim
Sie Parallelitätskontrolle erreichen.quelle
Meine einfache Implementierung von ParallelForEach async.
Eigenschaften:
Anwendungsbeispiel:
quelle
Ich habe hierfür eine Erweiterungsmethode erstellt, die SemaphoreSlim verwendet und es ermöglicht, einen maximalen Grad an Parallelität festzulegen
Beispielnutzung:
quelle