Nosila
Nosila

Reputation: 540

`RunWorkerCompleted` not being always being fired

I'm using several external services when items in my application are completed. Each service I must contact gets it's own BackgroundWorker to perform its task. I keep track of how many workers completed their work to determine if there were any errors. The issue I'm running into is that RunWorkerCompleted doesn't always get fired.

Here is what I have:

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();

What am I missing?

When it fails to get called I see The thread 0x2e0 has exited with code 0 (0x0). in my console.

I have changed the way I increment my count by using Interlocked but that hasn't changed anything. I know the event isn't being called because I have a breakpoint set.

Any ideas?

Upvotes: 1

Views: 743

Answers (3)

Gilad
Gilad

Reputation: 2886

I don't know but you are writing a multi-threaded procedure that shears global data without a single lock, something surly is going wrong.

Upvotes: 1

Servy
Servy

Reputation: 203802

You have race condition when incrementing completedCount. You should use Interlocked.Increment

Upvotes: 2

Rich O&#39;Kelly
Rich O&#39;Kelly

Reputation: 41757

Are you sure that the RunWorkerCompleted event is not raised? The most likely cause is that you're not incrementing the completedCount field properly. Try using the Interlocked methods:

Interlocked.Increment(ref completedCount);

Upvotes: 3

Related Questions