¿La función .net Parallel.ForEach bloquea el hilo de llamada? Supongo que el comportamiento es uno de estos:¿Parallel.ForEach Block?
- Sí, bloquea hasta que vuelve el elemento más lento que se ejecuta.
- No, no bloquea y devuelve el control inmediatamente. Los elementos para ejecutar en paralelo se realizan en hilos de fondo.
O tal vez está sucediendo algo más, ¿alguien lo sabe con certeza?
Esta pregunta se acercó la hora de implementar esto en una clase de registro:
public class MultipleLoggingService : LoggingServiceBase
{
private readonly List<LoggingServiceBase> loggingServices;
public MultipleLoggingService(List<LoggingServiceBase> loggingServices)
{
this.loggingServices = loggingServices;
LogLevelChanged += OnLogLevelChanged;
}
private void OnLogLevelChanged(object sender, LogLevelChangedArgs args)
{
loggingServices.ForEach(l => l.LogLevel = LogLevel);
}
public override LogMessageResponse LogMessage(LogMessageRequest request)
{
if (request.LogMessage)
Parallel.ForEach(loggingServices, l => l.LogMessage(request));
return new LogMessageResponse{MessageLogged = request.LogMessage};
}
}
Aviso LogMessage
el método llama a algunos otros servicios de registro. Necesito que esa parte vuelva de inmediato, por lo que no bloquea el hilo de llamada.
Actualización: En base a los comentarios de otras personas (que han confirmado el comportamiento es # 1). Así que he seguido el consejo de usar la biblioteca Task y reescrito el bucle de la siguiente manera:
if (request.LogMessage)
foreach (var loggingService in loggingServices)
Task.Factory.StartNew(() => loggingService.LogMessage(request));
Gracias por la punta! ¿Tiene un pequeño fragmento de código sobre cómo usar 'Tarea' en este contexto? Gracias, Paul –
@PaulFryer: 'Tarea t = Tarea.TaskFactory.StartNew (() => {/ * Paralelo.For va aquí * /});' – Richard
Técnicamente, el hilo de llamada se utiliza en el bucle paralelo. Por lo tanto, no se trata de un "desperdicio" que solo bloquea el ciclo; se usa como uno de los hilos de trabajo. –