猿问

如何阻止后台工作人员在表单的闭幕式上工作?

如何阻止后台工作人员在表单的闭幕式上工作?

我有一个生成背景工作器的表单,它应该更新表单自己的文本框(在主线程上),因此Invoke((Action) (...));打电话。
如果在HandleClosingEvent我只是想bgWorker.CancelAsync()然后我得到ObjectDisposedException在……上面Invoke(...)打电话,可以理解。但如果我坐在HandleClosingEvent等待bgWorker的完成,而不是.invoke(.)永远不会回来,也是可以理解的。

任何想法,我如何关闭这个应用程序而没有得到异常,或僵局?

以下是简单Form 1类的三种相关方法:

    public Form1() {
        InitializeComponent();
        Closing += HandleClosingEvent;
        this.bgWorker.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
        while (!this.bgWorker.CancellationPending) {
            Invoke((Action) (() => { this.textBox1.Text = Environment.TickCount.ToString(); }));
        }
    }

    private void HandleClosingEvent(object sender, CancelEventArgs e) {
        this.bgWorker.CancelAsync();
        /////// while (this.bgWorker.CancellationPending) {} // deadlock
    }


回首忆惘然
浏览 408回答 3
3回答

梵蒂冈之花

我所知道的唯一的死锁安全和异常安全的方法是实际上取消FormCling事件。如果BGW仍在运行,则设置e.Cancel=true,并设置标志以指示用户请求关闭。然后在BGW的RunWorkerCompleted事件处理程序中检查该标志,如果设置了它,则调用Close()。private bool closePending;protected override void OnFormClosing(FormClosingEventArgs e) {     if (backgroundWorker1.IsBusy) {         closePending = true;         backgroundWorker1.CancelAsync();         e.Cancel = true;         this.Enabled = false;   // or this.Hide()         return;     }     base.OnFormClosing(e);}void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {     if (closePending) this.Close();     closePending = false;     // etc...}

犯罪嫌疑人X

我找到了另一条路。如果您有更多的背景工作人员,您可以:List<Thread>&nbsp;bgWorkersThreads&nbsp;&nbsp;=&nbsp;new&nbsp;List<Thread>();在每个后台工作人员的DoWork方法中:bgWorkesThreads.Add(Thread.CurrentThread);您可以使用的Arter:foreach&nbsp;(Thread&nbsp;thread&nbsp;in&nbsp;this.bgWorkersThreads)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread.Abort();&nbsp;&nbsp;&nbsp;&nbsp;}我在Word外接程序控件中使用了这个,我在CustomTaskPane..如果有人提前关闭文档或应用程序,那么我所有的后台工作都完成了他们的工作,这会引发一些COM Exception(我记不清是哪一个)。CancelAsync()不管用。但是有了这个,我可以关闭所有由backgroundworkers立即进入DocumentBeforeClose我的问题解决了。
随时随地看视频慕课网APP
我要回答