停止后台工作线程不工作后关闭窗体

本文关键字:工作 窗体 线程 后台 | 更新日期: 2023-09-27 18:18:41

我一直在尝试许多不同的事情,但无法让这段代码工作。我的代码停止后台工作者然后关闭窗口。

protected override void OnFormClosing(FormClosingEventArgs e)
    {
        if (bw.IsBusy)
        {
            bw.CancelAsync();
            e.Cancel = true;
            MessageBox.Show("close"); //Does show
            return;
        }
        base.OnFormClosing(e);
    }

在 bw 工人期间

if (worker.CancellationPending)
        {
            MessageBox.Show("Cancel"); // Does not show
            //Cancel
            e.Cancel = true;
        }

在已完成的后台辅助角色上

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Completed"); //Does not work
        //Check if restart
        if (bw_restart)
        { 
            bw_restart = false;
            bw.RunWorkerAsync();
        }
        //If it was cancelled
        if (e.Cancelled)
        {
            this.Close();
        }
        //If error show error message
        else if (e.Error != null)
        {
            MessageBox.Show(e.Error.ToString()); // Does not show
        }
        else //No errors or cancelled
        {
            MessageBox.Show(e.ToString()); //Does not shoiw
        }
    }

"取消"按钮

private void cancel_Click(object sender, EventArgs e)
    {
        bw.CancelAsync(); //Does not work :s
    }

它不会关闭窗口,按下 X 时不做任何事情,我让它关闭表单,但没有停止后台工作线程,让我有点生气。链接到我为这个问题获得的代码,但不起作用:如何在窗体的关闭事件上停止后台工作者?

停止后台工作线程不工作后关闭窗体

   if (e.Cancelled)

这从根本上是错误的。 您永远无法 100% 确定它会被设置。 取消 BGW 始终是一种争用条件,当您调用其 CancelAsync(( 方法时,BGW 可能正忙于退出,因此从未看到 CancelPending 设置为 true,因此从未在 DoWork 事件处理程序中分配 e.Cancel = true。

事实上,您所知道的是mCloseEnding是可靠的,因为它在UI线程上设置为true。 所以总是调用 Close(( 它设置为 true,无论 e.Cancel 状态如何。

是的,检查e.Error也不会有什么坏处。 但仍然检查 m关闭待定.

如我的评论中所述,您的 BackgroundWorker 已因错误而结束,请尝试在运行工作线程已完成的顶部添加以下内容。一旦此错误得到解决,您的问题将更容易回答。

if(e.Error != null)
     MessageBox.Show(e.Error.toString());//Put a breakpoint here also

CancelAsync实际上并没有中止你的线程或类似的东西。它向工作线程发送一条消息,指出应通过 BackgroundWorker.CancelPending取消工作。在后台运行的 DoWork 委托必须定期检查此属性并处理取消本身。

看看这个:

    private BackgroundWorker background;
    private void Form1_Load(object sender, EventArgs e)
    {
        background = new BackgroundWorker();
        background.WorkerSupportsCancellation = true;
        background.DoWork += BackgroundOnDoWork;
        background.RunWorkerCompleted += BackgroundOnRunWorkerCompleted;
        background.RunWorkerAsync();
    }
    private void BackgroundOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
    {
        MessageBox.Show("stop");
    }
    private void BackgroundOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
    {
        // your doWork loop should check if someone don't call background.CancelAsync();
        while (!background.CancellationPending) 
        {
            // do something
        }
    }
    private void ButtonClick(object sender, EventArgs e)
    {
        background.CancelAsync();
    }