7

I am trying to figure out a way to verify that a BackgroundWorker thread is alive (i.e. still running. The thread is essentially implemented as a simple infinite loop:

while (AllConditionsMet())
{
  DoSomeMagic();
  Thread.Sleep(10000);
}

The closest thing to IsAlive() I found so far is the IsBusy property, but given that my thread Sleep()s most of the time, I am not sure whether this will do the job.

Can I count on IsBusy to do:

if (!myWorker.IsBusy)
  RestartWorker();

or am I calling for trouble?

Ghasem
  • 14,455
  • 21
  • 138
  • 171
scatmoi
  • 1,958
  • 4
  • 18
  • 32
  • 1
    if isBusy is false the Backgroundworker isn't doing a job, so you're not getting into trouble by using the shown code. Only the method "RestartWorker()" is wrong, because the Worker hasn't been started. But that's more a language thing than a programming issue. – jAC Oct 30 '12 at 13:12
  • 2
    You are asking for trouble if you implement code within the thread to restart itself. You would be better off, detecting a fail condition, ending tha thread and restarting an entirely new thread. Otherwise you could very likely have a deadlock situation. – Security Hound Oct 30 '12 at 13:12
  • Consider using "await Task.Delay(10000);" instead of your Thread.Sleep, it will likely achieve the same objectives while having less of an impact on everything else. – user2163234 Nov 06 '18 at 22:04

4 Answers4

15

BackgroundWorker.IsBusy is true as long as the DoWork event handler is busy and the RunWorkerCompleted event handler hasn't been run yet. Do note the latter clause, the property does not tell you if your loop is active.

Furthermore, there's a fairly nasty race condition in your second snippet. IsBusy might be true in the if() statement but be false a nanosecond later. The kind of race that strikes once a month. The intent of the code is hard to fathom from the snippets so hard to give a workaround. Consider just always creating a new BGW object, that will never race. Also helps getting rid of that loop, a thread sleeping for 10 seconds is wasting a very expensive system resource on doing nothing. And it gums-up the threadpool scheduler.

Ghasem
  • 14,455
  • 21
  • 138
  • 171
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
8

To make sure the Backgroundworker really stopped, you can kill it manually. Set yourBackgroundWorker.WorkerSupportsCancellation = true;. Then simply stop the Backgroundworker with:

yourBackgroundWorker.CancelAsync();

Still isBusy should be enough to detect a running/working instance of your BackgroundWorker.

jAC
  • 5,195
  • 6
  • 40
  • 55
4

From the docs:

true, if the BackgroundWorker is running an asynchronous operation; otherwise, false.

Regardless if you sleep the worker thread or not, it's still doing something so using IsBusy should be fine.

James
  • 80,725
  • 18
  • 167
  • 237
0

create a boolean variable, set the variable to true whenever backgroundworker start run, set the boolean variable to false after the backgroundworker is finish. Check the boolean variable status, it can show you is backgroundworker still running or not accurately.