Reputation: 540
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
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
Reputation: 203802
You have race condition when incrementing completedCount. You should use Interlocked.Increment
Upvotes: 2
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