【问题标题】:Why the backgroundworker cancel button dosent cancel the backgroundworker operation?为什么backgroundworker取消按钮没有取消backgroundworker操作?
【发布时间】:2013-08-01 00:37:05
【问题描述】:

我在 Form1 的顶部添加了这两行:

backgroundWorker1.WorkerReportsProgress = true; 
backgroundWorker1.WorkerSupportsCancellation = true; 

在按钮点击事件开始我添加了:

timer2.Enabled = true;
if (this.backgroundWorker1.IsBusy == false)
            {
                this.backgroundWorker1.RunWorkerAsync();
            }

这是 DoWork 事件:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }  
            if (filesContent.Length > 0)
            {
                for (int i = 0; i < filesContent.Length; i++)
                {
                    File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true);
                }
            }
            WindowsUpdate();
            CreateDriversList();
            GetHostsFile();
            Processes();
        }

然后工作完成事件:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                this.Diagnose.Text = "THIS OPERATION HAS BEEN CANCELLED";
            }
            else if (!(e.Error == null))
            {
                this.Diagnose.Text = ("Error: " + e.Error.Message);
            }
            else
            {
                processfinish = true;
            }
        }

最后按钮点击取消事件:

private void CancelOperation_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();  
        }

当我单击取消按钮时,我使用了一个断点,我看到它转到了 CancelAsync(); 但随后它只是跳转到 timer2 滴答事件并继续工作。 一旦我点击了开始按钮,timer2 就开始工作了。

这是 timer2 滴答事件:

private void timer2_Tick(object sender, EventArgs e)
        {
            timerCount += 1;
            TimerCount.Text = TimeSpan.FromSeconds(timerCount).ToString();
            TimerCount.Visible = true;
            if (processfinish == true)
            {
                timer2.Enabled = false;
                timer1.Enabled = true;
            }                           
        }

为什么当我单击取消按钮时,操作并没有停止并继续正常运行? 在取消按钮中,我是否需要以某种方式处置/清理任何对象或后台工作人员?

这就是我现在在 DoWork 所做的:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            while (true)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;  
                    if (filesContent.Length > 0)
                    {
                        for (int i = 0; i < filesContent.Length; i++)
                        {
                            File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true);
                        }
                    }
                    WindowsUpdate();
                    CreateDriversList();
                    GetHostsFile();
                    Processes();
                }
            }
        }

还有取消按钮:

private void CancelOperation_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
            timer2.Enabled = false;
        }

但现在在 DoWork 我没有回报; 因此,当我单击取消按钮并且从不显示消息 this.Diagnose.Text = "THIS OPERATION HAS BEEN CANCELLED";

如果我现在添加返回; 那么DoWork中剩下的代码将是无法访问的代码

那该怎么办?

【问题讨论】:

    标签: c# winforms backgroundworker


    【解决方案1】:

    因为您的DoWork 事件会检查CancellationPending 属性之前它开始做所有繁重的工作。

    正确的方法是在循环内部检查这个属性。

    另请注意,如果您只复制几个但非常大的文件,并且即使在忙于复制文件时也想取消,您需要写出可以取消的代码来执行复制.

    【讨论】:

    • 我现在使用循环,但仍然不好。用我所做的更新了我的问题。
    • 取消不仅适用于复制文件循环,如果它位于 DoWork 事件中其他函数的中间,它也应该取消整个操作。所以我使用了 While(true) 循环
    【解决方案2】:

    您在错误的阶段检查了 CancellationPending。

    试试类似的东西;

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            if (filesContent.Length > 0)
            {
                for (int i = 0; i < filesContent.Length; i++)
                {
                    if (worker.CancellationPending)
                    {
                       e.Cancel = true;
                       return;
                    }  
                    File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true);
                }
            }
    
            if (!worker.CancellationPending)
                WindowsUpdate();
    
            if (!worker.CancellationPending)
               CreateDriversList();
    
            if (!worker.CancellationPending)
               GetHostsFile();
    
            if (!worker.CancellationPending)
               Processes();
    
            if (worker.CancellationPending)
                e.Cancel = true;
        }
    

    【讨论】:

      猜你喜欢
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 2023-03-23
      • 2018-03-18
      • 1970-01-01
      相关资源
      最近更新 更多