2012-02-22 95 views
1

当我的应用程序中的项目完成时,我正在使用几个外部服务。我必须联系的每项服务都有自己的BackgroundWorker来执行其任务。我跟踪有多少工人完成了他们的工作,以确定是否有任何错误。我遇到的问题是RunWorkerCompleted并不总是被解雇。`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增加计数的方式,但这并没有改变任何东西。我知道事件没有被调用,因为我有一个断点。

任何想法?

回答

3

是否确定RunWorkerCompleted事件没有引发?最可能的原因是您没有正确增加completedCount字段。尝试使用Interlocked methods

Interlocked.Increment(ref completedCount); 
+0

我很确定,因为我在那里设置了一个断点。另外,当它未能被调用时,我看到'线程0x2e0已经退出,并且在我的控制台中有代码0(0x0).'。 – Nosila 2012-02-22 16:44:25

2

您递增completedCount当有竞争状态。你应该使用Interlocked.Increment

1

我不知道,但你正在编写一个多线程的程序,剪切全局数据没有一个锁,有些东西出错了。