2012-02-22 2 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

2

completedCountをインクリメントするときには競合状態を持っています。 Interlocked.Incrementを使用する必要があります

1

単なるロックなしでグローバルデータを剪断するマルチスレッドプロシージャーを作成していますが、間違っています。