views:

313

answers:

2

Hello,

I use backgroundworker objects to preform some async and threading where needed. Every once in awhile when I run the backgroundworker it stalls in the middle of running and doesn't finish. It usually does this when I am running more then 1 backgroundworker at the same time.

What I want to do when it stalls is cancel the operation and re-run it. My problem is I don't know how to detect when it has stalled. Is there some code I need to add to "notify" that the worker has stalled or is there no way to know?

Thanks,

+2  A: 

That depends entirely on what you mean by "stalled". If you have managed to deadlock the worker thread, then you'll need to find the problem and unpick the mess. If it is throwing an exception, then the RunWorkerCompleted event should fire, with a non-null Error in the event-args.

Marc Gravell
RunWorkerCompleted doesn't get called. You and sambo had the same idea on the deadlock so I'm gonna check that out. Thanks.
Phillip
Marc, I updated my answer, still think there is one missing override on RunWorkerAsync, it should allow you to specify a timeout to make it easier to enforce an SLA. Also I kind of like passing Actions around better than subscribing to events, if feels less side effecty, but its just a personal taste thing.
Sam Saffron
We still are having no luck finding the deadlock so we decided that for this part of the code we will just run it without the worker, use the main thread instead. I will come back to it later I think and try to figure it out. Thanks.
Phillip
+4  A: 

You should debug your code and figure out why its stalling.

  • Do you have a multithreaded deadlock?
  • Are resource pools exhausted?
  • Are you waiting indefinitely on a network resource?
  • Is an exception thrown mid process?

BackgroundWorker provides the following callback:

  • DoWork, which is called before your work starts.
  • RunWorkerCompleted, which is called when your work is done.

You could extend this with a wrapper to log a warning if the action takes longer than a certain amount of time if you want to enforce some sort of service level for async actions. (Eg. start a timer when DoWork is called and when the timer elapses log the warning, clear timer when complete)

Sam Saffron
There isn't any network resources being accessed, it's actually calculating reports from data received before the worker got started so the data is local. I'll have to check on Deadlocks. Thanks.
Phillip
He isn't queueing on ThreadPool - he's using BackgroundWorker, which already does this wrapping...
Marc Gravell
True, will remove this sample cause it just causes confusion
Sam Saffron