Me gustaría manejar una colección en paralelo, pero tengo problemas para implementarla y, por lo tanto, espero ayuda.
El problema surge si quiero llamar a un método marcado asíncrono en C #, dentro de la lambda del bucle paralelo. Por ejemplo:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
// some pre stuff
var response = await GetData(item);
bag.Add(response);
// some post stuff
}
var count = bag.Count;
El problema ocurre cuando el recuento es 0, porque todos los subprocesos creados son efectivamente solo subprocesos en segundo plano y la Parallel.ForEachllamada no espera su finalización. Si elimino la palabra clave asíncrona, el método se ve así:
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
// some pre stuff
var responseTask = await GetData(item);
responseTask.Wait();
var response = responseTask.Result;
bag.Add(response);
// some post stuff
}
var count = bag.Count;
Funciona, pero deshabilita por completo la agudeza de espera y tengo que hacer un manejo manual de excepciones. (Eliminado por brevedad).
¿Cómo puedo implementar un Parallel.ForEachbucle que usa la palabra clave wait dentro de lambda? ¿Es posible?
El prototipo del método Parallel.ForEach toma un Action<T>parámetro como, pero quiero que espere mi lambda asíncrona.

awaitdeawait GetData(item)en su segundo bloque de código, ya que produciría un error de compilación como está.Respuestas:
Si solo quieres un paralelismo simple, puedes hacer esto:
Si necesitas algo más complejo, mira la
ForEachAsyncpublicación de Stephen Toub .fuente
doptareas y cada una de ellas procesa algún subconjunto de la colección de entrada en serie.Task.Runsin obtenerawaitel resultado, entonces eso es solo lanzar trabajo de disparar y olvidar en el grupo de subprocesos. Eso casi siempre es un error.Puede usar el
ParallelForEachAsyncmétodo de extensión del paquete AsyncEnumerator NuGet :fuente
maxDegreeOfParallelism>maxDegreeOfParalellismCon
SemaphoreSlimusted puede lograr el control de paralelismo.fuente
Mi implementación ligera de ParallelForEach async.
caracteristicas:
Ejemplo de uso:
fuente
He creado un método de extensión para esto que hace uso de SemaphoreSlim y también permite establecer el grado máximo de paralelismo
Uso de muestra:
fuente