停止背景工作者不工作后关闭窗体

时间:2013-06-17 18:46:03

标签: c# visual-studio

我一直在尝试许多不同的东西,无法让这些代码工作。我的代码停止后台工作,然后关闭窗口。

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没有做任何事情,我得到了关闭表格而不是停止后台工作人员,让我有点生气。链接到我为此问题得到的代码无效:How to stop BackgroundWorker on Form's Closing event?

3 个答案:

答案 0 :(得分:2)

   if (e.Cancelled)

这是根本错误的。你永远不能100%确定它会被设置。取消BGW始终是竞争条件,BGW可能在您调用CancelAsync()方法时一直忙于退出,因此从未将CancellationPending设置为true,因此从未在DoWork事件处理程序中分配e.Cancel = true。

所有你知道的事实是mClosePending是可靠的​​,因为它在UI线程上设置为true。因此,无论e.Cancelled状态如何,总是调用Close()它设置为true。

是的,检查e.Error也没有伤害。但是仍然检查mClosePending。

答案 1 :(得分:1)

正如我的评论所述,您的BackgroundWorker因错误而终止,请尝试在运行工作者的顶部添加以下内容。一旦此错误得到解决,您的问题将更加可以回答。

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

答案 2 :(得分:0)

CancelAsync实际上并没有中止你的线程或类似的东西。它向工作线程发送一条消息,通过BackgroundWorker.CancellationPending取消工作。您在后台运行的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();
    }