BackgroundWorker的IsBusy和"IsAlive"一样吗?

7
我正在尝试找出一种验证BackgroundWorker线程是否存活(即仍在运行)的方法。该线程基本上是实现为一个简单的无限循环:
while (AllConditionsMet())
{
  DoSomeMagic();
  Thread.Sleep(10000);
}

到目前为止,我找到的最接近IsAlive()的东西是IsBusy属性,但考虑到我的线程大部分时间都在睡眠,我不确定这是否能胜任工作。

我能否依靠IsBusy来做到:

if (!myWorker.IsBusy)
  RestartWorker();

还是我自找麻烦?


1
如果isBusy为false,则Backgroundworker不会执行任务,因此使用所示代码不会有问题。只有方法“RestartWorker()”是错误的,因为Worker尚未启动。但这更多是语言问题而不是编程问题。 - jAC
2
如果您在线程内部实现代码以重新启动自身,那么您将会自找麻烦。最好的方法是检测失败条件,结束该线程并重新启动一个全新的线程。否则,您很可能会遇到死锁情况。 - Security Hound
考虑使用"await Task.Delay(10000);"代替Thread.Sleep,它可能会在实现相同目标的同时对其他操作产生较小的影响。 - user2163234
4个回答

15

BackgroundWorker.IsBusy 属性在 DoWork 事件处理程序忙碌 RunWorkerCompleted 事件处理程序未运行时为 true。请注意后一子句,该属性不会告诉您循环是否处于活动状态。

此外,第二个代码片段中存在相当恶劣的竞争条件。在 if() 语句中 IsBusy 可能为 true,但在一纳秒后可能为 false。这是每月发生的一种竞争情况。由于无法理解代码片段的意图,因此难以提供解决方法。考虑始终创建新的 BGW 对象,这将永远不会有竞争情况。这有助于消除循环,沉睡10秒的线程正在浪费非常昂贵的系统资源。并阻塞了线程池调度程序。


8
为确保Backgroundworker真正停止,您可以手动终止它。 设置yourBackgroundWorker.WorkerSupportsCancellation = true;。 然后只需使用以下代码停止Backgroundworker:
yourBackgroundWorker.CancelAsync();

但是isBusy足以检测你的BackgroundWorker正在运行/工作。


4

根据文档

true表示BackgroundWorker正在运行异步操作;否则,false

无论您是否使工作线程休眠,它仍在执行某些操作,因此使用IsBusy应该是可以的。


0
创建一个布尔变量,每当后台工作器开始运行时将变量设置为true,当后台工作器完成后将布尔变量设置为false。检查布尔变量的状态,它可以准确地显示后台工作器是否仍在运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接