processo parallelo una funzione IO intensiva
-
27-10-2019 - |
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
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);
}
});