La funzione .net Parallel.ForEach blocca il thread chiamante? La mia ipotesi sul comportamento è uno di questi:Parallel.ForEach Block?
- Sì, blocca fino a quando l'elemento più lento in esecuzione restituisce.
- No, non blocca e restituisce il controllo immediatamente. Gli articoli da eseguire in parallelo sono fatti su thread in background.
O forse sta succedendo qualcos'altro, qualcuno lo sa per certo?
Questa domanda è venuto quando l'applicazione del presente in una classe di registrazione:
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};
}
}
Avviso il metodo LogMessage
chiama alcuni altri servizi di registrazione. Ho bisogno che quella parte ritorni immediatamente, quindi non blocca il thread chiamante.
Aggiornamento: in base ai commenti degli altri (abbiamo confermato il comportamento è # 1). Così ho seguito il consiglio di utilizzare la libreria Task e riscritto il ciclo come questo:
if (request.LogMessage)
foreach (var loggingService in loggingServices)
Task.Factory.StartNew(() => loggingService.LogMessage(request));
Grazie per la punta! Ti capita di avere un piccolo frammento di codice su come usare "Task" in questo contesto? Grazie, Paul –
@PaulFryer: 'Task t = Task.TaskFactory.StartNew (() => {/ * Parallel.Per andare qui * /});' – Richard
Tecnicamente, il thread chiamante viene utilizzato nel ciclo parallelo. Quindi non è "sprecato" solo bloccando il ciclo - è usato come uno dei thread di lavoro. –