如何在点击触发的backgroundWorker中添加一段代码?

Posted

技术标签:

【中文标题】如何在点击触发的backgroundWorker中添加一段代码?【英文标题】:How to add a piece of code to a backgroundWorker that is triggered by click? 【发布时间】:2013-05-07 12:20:50 【问题描述】:

我需要处理大量的 file.copy,这使我的 form1 “没有响应”并且我的程序显示死锁异常,所以我想创建一个 backgroundWorker 来处理所有主要处理。 我做了什么:

按钮:

if (backgroundWorker1.IsBusy != true)
            
                backgroundWorker1.RunWorkerAsync();
            

工作:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    
        BackgroundWorker worker = sender as BackgroundWorker;
        bool continueWork = true;

        while (continueWork)
        
            if ((worker.CancellationPending == true))
            
                e.Cancel = true;
                break;
            
            else
            
                foreach (string name in listFiles) //global list
                
                    string destwithFilename= dest + "\\" + Path.GetFileName(name);
                    try
                     File.Copy(name, destwithFilename, false);
                    catch (Exception EX_NAME)
                    
                        Console.WriteLine(EX_NAME);
                    
                    worker.ReportProgress((1));
                
                pbStatus.Increment(50); //Error, I can't access form1, another thread.
                continueWork = false; //If job is done, break;
                System.Threading.Thread.Sleep(500);
            
        
    

问题:

1) Form1 仍然显示为“未响应”;

2) 无法访问Form1;

3) 即使有 backgroundWorker,DeadLock 异常仍然出现。 //也许我应该禁用托管调试助手

编辑

工作

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    
        BackgroundWorker worker = sender as BackgroundWorker;
        bool continueWork = true;

        while (continueWork)
        
            foreach (string name in Files) //Global
            
                if ((worker.CancellationPending == true))
                
                    e.Cancel = true;
                    break;
                
                else
                
                    string destwithFilename= dest + "\\" + Path.GetFileName(name);
                    try
                    
                        File.Copy(name, destwithFilename, false); //no overwritting
                        worker.ReportProgress((1));
                        //System.Threading.Thread.Sleep(50);
                    
                    catch (Exception EX_NAME)
                    
                        Console.WriteLine(EX_NAME);
                    
                
            
            continueWork = false;
        
    

进度改变:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    
        pbProcess.Value = e.ProgressPercentage;
        if (pbProcess.Value == pbProcess.Maximum)
        
            cbFinal.Checked = true;
        
    

结果:

输出真的很慢,但现在我的表单继续工作而没有“没有响应”。 pbProcess 不增加,我不知道为什么。 pbProcess 是一个进度条。

【问题讨论】:

对于第二个问题(不能从anotehr线程访问表单),应该使用backgroundworker对象的ReportProgress()方法更新进度并注册到ProgressChanged事件中调用表单更新进度条状态。 是的,我已经这样做了。但我不明白的是,即使使用 backgroundWorker,我的表单仍然碰巧“没有响应”。 :// 您应该在 foreach 循环中查询 CancelationPending,这样您才能真正停止文件复制操作。 【参考方案1】:

要报告进度,您应该:

WorkerReportsProgress 属性设置为True 使用后台worker的ReportProgress()方法报告进度 然后,处理后台工作人员的ProgressChanged 事件。并设置您的 pbStatus 的值

代码:

报告进度

backgroundWorker1.ReportProgress(50);

处理 ProgressChanged 事件

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

      pbStatus.Value = e.ProgressPercentage;

进展

对于进度,您使用 ReportProgress(1) 报告进度,这会将进度条的值设置为 1,并且不会增加 1

int cpt = 1;
int totalFilesCount = listFiles.Count;

foreach (var field in listFiles)

      // Copy the file ...

      backgroundWorker1.ReportProgress((cpt / totalFilesCount) * 100);
      cpt++;

【讨论】:

pbStatus.Value = e.ProgressPercentage; //对吗? 是:pbStatus.Value = e.ProgressPercentage; // 我以为是方法 你的From1的问题还存在吗? 不用了,我改了我的代码,但是现在 ProgressChanged 不工作了...我会放我的代码。 使用您的代码,我设置了一个断点... e.ProgressPercentage 始终为零。

以上是关于如何在点击触发的backgroundWorker中添加一段代码?的主要内容,如果未能解决你的问题,请参考以下文章

WP7 为两个 BackgroundWorker 对象触发一个 RunWorkerCompleted 事件

BackgroundWorker RunWorkerCompleted 事件

c# 关于backgroundWorker的取消

winform BackgroundWorker的使用

如何在窗体的关闭事件中停止 BackgroundWorker?

如何正确实现 BackgroundWorker 以通知用户任务正在进行中