为什么后台工作人员取消按钮没有取消后台工作人员操作

本文关键字:取消 工作人员 后台 取消后 操作 按钮 为什么 | 更新日期: 2023-09-27 18:25:45

我在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();但它只是跳到时间2滴答事件并继续工作。当我点击开始按钮时,timer2就开始工作了。

这是timer2 tick事件:

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,我没有回报;因此,当我单击取消按钮时,它永远不会到达已完成的事件,也不会显示此消息。Diagnose.Text="此操作已取消";

如果我现在加上返回;然后DoWork中的其余代码将无法访问代码

那该怎么办?

为什么后台工作人员取消按钮没有取消后台工作人员操作

因为DoWork事件在之前检查了CancellationPending属性,所以它开始执行所有繁重的工作。

正确的方法是在循环内检查此属性

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

您在错误的阶段检查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;
    }