Domanda

Ho questo codice di esempio.

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

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

Ho bisogno di elaborare l'URL, processUrl verso il basso carico della pagina e eseguire molte espressioni regolari per estrarre alcune informazioni e restituire un "C # JSON come" oggetto, quindi voglio eseguire questo in parallelo e alla fine ho bisogno di un elenco di oggetti in modo ho bisogno di aspettare tutti i compiti di continuare processo, come posso fare questo? Io se molti esempio ma nessuno salvare il ritorno.

Saluti

È stato utile?

Soluzione

Ti piace questa?

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

Con Parallel:

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

o

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

o di Attività:

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

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

Altri suggerimenti

In primo luogo, refactoring come

processUrl(url, objects);

e rendere il compito responsabile per aggiungere i risultati alla lista.

Quindi aggiungere il blocco così due compiti in parallelo non cercano di utilizzare l'elenco dei risultati esattamente nello stesso momento.


. Nota: il supporto async nella prossima versione di .NET renderà questo banalmente facile

È possibile utilizzare le estensioni PLINQ, questo richiede il .NET 4.0

System.Threading.Tasks.Parallel
          .ForEach(urls, url => {
             var result = processUrl(url);
             lock(objects)
             {
                  objects.Add(result);
             }
           });
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top