当我的应用程序中的项目完成时,我正在使用多个外部服务。我必须联系的每项服务都有自己的BackgroundWorker
来执行其任务。我会跟踪有多少工人完成工作以确定是否有任何错误。我遇到的问题是RunWorkerCompleted
并不总是被解雇。
这就是我所拥有的:
var exceptionsCaught = new List<Exception>();
var completedCount = 0;
foreach(var notificationToSend in NotificationQueue)
{
var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += (sender, b) => notificationToSend();
backgroundWorker.RunWorkerCompleted += (sender, args) =>
{
Console.WriteLine("Done.");
if(args.Error != null)
{
exceptionsCaught.Add(args.Error);
Console.WriteLine("Error! {0}", args.Error.Message);
}
completedCount++;
};
backgroundWorker.RunWorkerAsync();
}
var exceptionCheckerWorker = new BackgroundWorker();
exceptionCheckerWorker.DoWork += (sender, b) =>
{
while (true)
{
if (completedCount != NotificationQueue.Count) continue;
if (exceptionsCaught.Any())
{
var notificationExceptionMessage =
new NotificationExceptionsMessage(exceptionsCaught,
_notificationGeneratedPath);
_eventAggregator.Publish(notificationExceptionMessage);
break;
}
break;
}
};
exceptionCheckerWorker.RunWorkerAsync();
我错过了什么?
如果无法调用,我会在控制台中看到The thread 0x2e0 has exited with code 0 (0x0).
。
我改变了使用Interlocked
增加计数的方式,但这没有改变任何东西。我知道事件没有被调用,因为我有一个断点设置。
有什么想法吗?
答案 0 :(得分:3)
您确定RunWorkerCompleted
事件未被提出吗?最可能的原因是您没有正确递增completedCount
字段。尝试使用Interlocked methods:
Interlocked.Increment(ref completedCount);
答案 1 :(得分:2)
增加completedCount时有竞争条件。你应该使用Interlocked.Increment
答案 2 :(得分:1)
我不知道,但是你正在编写一个多线程程序,可以在没有单一锁定的情况下剪切全局数据,这有点不对。