Pau*_*yer 47 .net c# parallel-processing logging multithreading
.net函数Parallel.ForEach是否会阻塞调用线程?我对行为的猜测是以下之一:
或许其他事情正在发生,任何人都知道吗?
在日志记录类中实现此问题时出现了这个问题:
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};
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,该LogMessage
方法调用其他一些日志服务.我需要该部分立即返回,因此它不会阻止调用线程.
更新:根据其他人的评论(我们已确认行为是#1).所以我已经建议使用Task库并重写循环,如下所示:
if (request.LogMessage)
foreach (var loggingService in loggingServices)
Task.Factory.StartNew(() => loggingService.LogMessage(request));
Run Code Online (Sandbox Code Playgroud)
Gab*_*abe 57
1号是正确的; Parallel.ForEach
在循环完成之前不会返回.如果你不想要这种行为,你可以简单地执行你的循环Task
并在另一个线程上运行它.
Hen*_*man 10
在正常的foreach()中重新更新,StartNew:
对于大型集合而言,这可能不是最佳选择,并且您无法处理错误.
您的loggingServices可能不包含数千个项目,但错误处理仍然是一个问题.
考虑:
Task.Factory.StartNew(() =>
{
try
{
Parallel.ForEach(loggingServices, l => l.LogMessage(request));
}
catch(SomeException ex)
{
// at least try to log it ...
}
});
Run Code Online (Sandbox Code Playgroud)