Frage

Ich habe diesen Beispielcode.

List<Dictionary<string,string>> objects = new List<Dictionary<string,string>>();

foreach (string url in urls)
{
    objects.add(processUrl(url))
}

Ich muss die URL verarbeiten, processUrl Laden Sie die Seite herunter und führen Sie viele Regex aus, um einige Informationen zu extrahieren und ein "C# json -ähnliches" -Objekt zurückzugeben. Daher möchte ich dies parallel ausführen. Am Ende benötige ich eine Liste von Objekten, sodass ich alle Aufgaben warten muss, um den Prozess fortzusetzen Wie kann ich das erreichen? Ich habe viele Beispiele, aber keiner speichert die Rückkehr.

Grüße

War es hilfreich?

Lösung

So was?

var results = urls.AsParallel().Select(processUrl).ToList();

Mit Parallel:

Parallel.ForEach(
    urls, 
    url =>
    {
        var result = processUrl(url);
        lock (syncOjbect)
            objects.Add(result);
    };

oder

var objects = new ConcurrentBag<Dictionary<string,string>>();
Parallel.ForEach(urls, url => objects.Add(processUrl(url)));
var result = objects.ToList();

oder mit Aufgaben:

var tasks = urls
    .Select(url => Task.Factory.StartNew(() => processUrl(url)))
    .ToArray();

Task.WaitAll(tasks);
var restuls = tasks.Select(arg => arg.Result).ToList();

Andere Tipps

Zunächst refaktor als

processUrl(url, objects);

und machen Sie die Aufgabe für das Hinzufügen der Ergebnisse zur Liste verantwortlich.

Fügen Sie dann das Sperren hinzu, damit zwei parallele Aufgaben nicht genau zur gleichen Zeit die Ergebnisliste verwenden.


Notiz: async Die Unterstützung in der nächsten Version von .NET macht dies trivial einfach.

Sie können Plinq -Erweiterungen verwenden, dies erfordert .NET 4.0

System.Threading.Tasks.Parallel
          .ForEach(urls, url => {
             var result = processUrl(url);
             lock(objects)
             {
                  objects.Add(result);
             }
           });
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top