Wie sammle ich Rückgabewerte von Parallel.ForEach?
Nenne ich eine langsame webservice parallel. Die Dinge waren großartig, bis ich erkannte, dass ich brauchen, um einige Informationen vom Dienst zurück. Aber ich sehe nicht, wo man die Werte zurück. Ich kann nicht in die Datenbank schreiben, HttpContext.Aktuelle zu sein scheint null innerhalb einer Methode aufgerufen, über die Parallel.ForEach
Unten ist ein Beispiel-Programm (in deinem Geist, bitte stellen Sie sich eine langsame web service anstelle der string-Verkettung)
using System;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
WordMaker m = new WordMaker();
m.MakeIt();
}
public class WordMaker
{
public void MakeIt()
{
string[] words = { "ack", "ook" };
ParallelLoopResult result = Parallel.ForEach(words, word => AddB(word));
Console.WriteLine("Where did my results go?");
Console.ReadKey();
}
public string AddB(string word)
{
return "b" + word;
}
}
}
Kommentar zu dem Problem
Eine andere überladung von
Parallel.ForEach
kann das sein, was Sie wollen: msdn.microsoft.com/en-us/library/dd991486.aspx Leider ist nicht wirklich etwas, das Sie tun können, dass.
Parallel.Foreach()
nur noch nicht gebaut war zum verfolgen gibt. Ich würde jedoch empfehlen die Verwendung von ref
- Parameter im AddB
Funktion. Das könnte es tun. @PhillipSchmidt: Nicht mit der überlastung in dem Beispiel verwendet sowieso...
@AustinSalonen, Was eine weitere überladung, die funktionieren würde? Ich argumentiere nicht, ich war einfach nicht bewusst, dass alles tun würde, was er will.
@PhillipSchmidt Den link in meinem ersten Kommentar explizit behandelt, eine
Func<...>
statt Action - <...>
InformationsquelleAutor der Frage MatthewMartin | 2012-09-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie verworfen es hier.
Möchten Sie wahrscheinlich so etwas wie,
Wenn Sie möchten, irgendeine Art von Auflistung am Ende dieser, sollten Sie verwenden eine der Sammlungen unter
System.Collections.Concurrent
wieConcurrentBag
InformationsquelleAutor der Antwort M Afifi
Ihr können überlegen
AsParallel
Erweiterung Methode derIEnumerable
es kümmert sich um die Parallelität für Sie und sammeln Sie die Ergebnisse.words.AsParallel().Select(AddB).ToArray()
Synchronisation (z.B. Schlösser oder concurrent collections, sperren) sind in der Regel Engpass von konkurrierenden algorithmen. Das beste ist das vermeiden von synchronisation so viel wie möglich. Ich vermute, dass
AsParallel
verwendet etwas schlauer, wie wenn man alle hergestellten Gegenstände einzigen thread in einem lokalen non-concurrent collection und dann kombinieren Sie diese am Ende.InformationsquelleAutor der Antwort Steves
Nicht verwenden
ConcurrentBag
um Ergebnisse zu sammeln, wie es ist extrem langsam.Verwenden Sie lokale Sperre statt.
InformationsquelleAutor der Antwort Minh Nguyen
Wie wäre es mit etwas wie dieses:
Glaube ich, dass die Sperr-oder Auger-Objekte ist nicht erforderlich, es sei denn, Sie müssen die Ergebnisse mit einer anderen interagieren kann (wie Sie die Berechnung einer Summe oder Kombination aller Worte). In diesem Fall ist ForEach ordentlich bricht Ihrer ursprünglichen Liste und Hände jeder thread sein eigenes Objekt, das Sie manipulieren können, alles, was Sie will, ohne sich Gedanken über stören die anderen threads.
InformationsquelleAutor der Antwort MichaC
Dieser scheint schnell, sicher und einfach:
InformationsquelleAutor der Antwort Overlord Zurg