En parallèle.ForEach avec l'ajout à la liste
Je suis en train d'exécuter plusieurs fonctions qui se connectent à un site distant (par le réseau) et de retourner une liste générique. Mais je tiens à les exécuter simultanément.
Par exemple:
public static List<SearchResult> Search(string title)
{
//Initialize a new temp list to hold all search results
List<SearchResult> results = new List<SearchResult>();
//Loop all providers simultaneously
Parallel.ForEach(Providers, currentProvider =>
{
List<SearchResult> tmpResults = currentProvider.SearchTitle((title));
//Add results from current provider
results.AddRange(tmpResults);
});
//Return all combined results
return results;
}
Comme je le vois, à de multiples reprises à des "résultats" peuvent se passer en même temps... ce Qui peut se bloquer ma demande.
Comment puis-je éviter cela?
- Qui .NET version utilisez-vous?
- Il faudrait au moins .Net 4; Parallèle y est implantée.
InformationsquelleAutor shaharmor | 2011-11-03
Vous devez vous connecter pour publier un commentaire.
Fondamentalement un verrou signifie qu'un seul thread peut avoir accès à la section critique en même temps.
this
n'est pas le choix le plus sûr pour le verrouillage de l'objet. Mieux vaut utiliser un objet privé:lock(resultsLock)
.locks
peut ralentir le temps d'exécution global mais.. simultanées collections semblent mieux éviter qu'lock(results)
puis y ajouter ce qui est mal ? Verrouillage au niveau de la classe de moyens, si plusieurs demandes sont en appelantSearch
alors vous avez dégradé les performancesVous pouvez utiliser un la collecte simultanée.
Vous pouvez par exemple utiliser
ConcurrentBag
puisque vous n'avez aucune garantie ordre dans lequel les éléments seront ajoutés.Simultanée de l'Collections sont nouveaux pour .Net 4; ils sont conçus pour fonctionner avec le nouveau parallèle de la fonctionnalité.
Voir Les Collections simultanées dans l' .NET Framework 4:
Pour ceux qui préfèrent le code:
Cela pourrait être exprimé de manière concise à l'aide de PLINQ
AsParallel
etSelectMany
:SearchTitle
se connecte à un site distant. Son temps de latence seront de plusieurs ordres de grandeur inférieure à celle de la différence entre LINQ for et foreach.