后台工作者配置vs thread.abort

时间:2017-12-11 21:06:38

标签: c# multithreading

bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerAsync();

void bg_DoWork(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        label1.Text = DateTime.Now.Minute.ToString() + " " + DateTime.Now.Second.ToString();
    }
}

bg.DoWork -= new DoWorkEventHandler(bg_DoWork);
bg.Dispose();

在调用此内容后,我发现BackgroundWorker仍然有效。但是,如果我使用BackgroundWorker并调用Thread而不是Abort(),那么它将取代sum(d for d in ds.data_vars.values()) 。为什么会这样?

3 个答案:

答案 0 :(得分:2)

RunWorkerAsync产生一个线程。调用Abort()故意终止此线程,而Dispose()处理后台工作程序实例。工作线程不会从此处置通知,并将很乐意继续执行。

事实上,BackgroundWorker只是因为inherits from Component而是一次性的。 Component的dispose逻辑负责容器和事件处理程序绑定,但BackgroundWorker本身在处理时没有任何东西可以清理。

答案 1 :(得分:1)

实际上,你正在为BackgroundWorker分配一个无限任务(这是因为while (true)必须实现一个显式命令来停止无限循环,如break语句或{ {1}}声明)。

一旦触发了方法处理程序(通过调用return),无论你做什么,它都将继续运行。

取消订阅事件处理程序不会阻止它,因为在彩虹的某个地方,节目必须继续。

处置bg.RunWorkerAsync()实例也不会阻止它。 BackgroundWorker类派生自BackgroundWorker(实现Component接口)并继承IDisposable方法,但不覆盖它。在其基本实现中,Dispose()仅授予从Component.Dispose()集合中删除组件并引发components事件...但正在创建的线程不会被杀死

保持您当前的设计,阻止Disposed的唯一方法是在创建时将其BackgroundWorker属性设置为true:

WorkerSupportsCancellation

然后致电:

bg = new BackgroundWorker();
bg.WorkerSupportsCancellation = true;

需要时。避免bg.CancelAsync(); 方法,它不安全。

答案 2 :(得分:0)

type BehaviorTree struct { Behavior Root IBehavior } func (n *BehaviorTree) Tick() Status { n.Update() // TODO: do you want this status or the Root.Tick() status? return n.Root.Tick() } func (n *BehaviorTree) Update() Status { fmt.Printf("Tree tick! %#v\n", n.Root) return nil } 没有代码可以中止线程(您可以检查代码referencesource)。您应该正确取消后台作业,而不是杀死该线程。例如,

BackgroundWorker