C# backgroundworker后台的进度条和运行方法

C# backgroundworker后台的进度条和运行方法,c#,.net,winforms,progress-bar,backgroundworker,C#,.net,Winforms,Progress Bar,Backgroundworker,我在表单中创建backgroundworker流程 BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; 另外,我在表单中有一个进度条控件(进度条最小值和最大值分别为1和100) 在我的按钮点击 单击事件将触发实际的方法调用,这些调用应该在后

我在表单中创建backgroundworker流程

 BackgroundWorker bw = new BackgroundWorker
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true
        };  
另外,我在表单中有一个进度条控件(进度条最小值和最大值分别为1和100)

在我的按钮点击

单击事件将触发实际的方法调用,这些调用应该在后台并行运行,开始显示进度条步骤

if (bw.IsBusy)
 {
    return;
 }

 bw.DoWork += (bwSender, bwArg) =>
 {
   MethodCall1(); - Does some database insertions..
   MethodCall2(); - Does some database select...
 }

bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw.RunWorkerCompleted += (bwSender, bwArg) =>
{

  bw.Dispose();                  
};

bw.RunWorkerAsync();
用于进度条以显示正在进行的

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   progressBar.Value = e.ProgressPercentage;
}
我面临的问题是,进度条并没有前进,它静止不动,没有进度条的进度

我还尝试在我的实际方法中插入bw.ReportProgress(integervalue),但没有帮助


如何让backgroundworker线程处理方法调用并并行显示进度条的进度,在方法调用完成后,我想结束进度条步骤。

如注释中所述,您应该将事件的关联向上移动到表单构造函数或初始化方法。如果在每次单击按钮时将它们添加到BackgroundWorker,那么这些方法将在第二次单击时执行两次,在第三次单击时执行三次,以此类推

尝试将ReportProgress调用放在DoWork代码中的方法调用之后。正如Hans在上面所说的,除非您对方法调用相互之间的相对时间有很好的了解,否则这并不能真正准确地表示进度

对于Dispose,BackgroundWorker继承自组件,该组件实现IDisposable。但是,BackgroundWorker不会覆盖基本实现来实际处理任何内容,因此调用它只是将其从components集合中删除。它不需要显式调用

试着这样做:

public partial class Form1 : Form
{
    BackgroundWorker bw = new BackgroundWorker
    {
        WorkerReportsProgress = true,
        WorkerSupportsCancellation = true
    };  

    public Form1()
    {
        InitializeComponent();

        bw.DoWork += (bwSender, bwArg) =>
        {
            //MethodCall1(); - Does some database insertions..
            bw.ReportProgress(50);
            //MethodCall2(); - Does some database select...
            bw.ReportProgress(100);
        };

        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

        bw.RunWorkerCompleted += (bwSender, bwArg) =>
        {

        };
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (bw.IsBusy)
        {
            return;
        }

        bw.RunWorkerAsync();
    }

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }
}

如果在bw_ProgressChanged中设置断点,是否已达到该断点?e.ProgressPercentage是否具有您期望的值?与e.ProgressPercentage中的值相比,progressBar的最小/最大值是多少?显然,您的代码缺少必需的ReportProgress()调用,因此进度条不会移动。计算一个有意义的进度值并不总是可能的,因为您并不总是对数据库引擎的工作了解得足够多。唯一的选择是使用ProgressBar.Style=Marquee。“处理它,而不是死”选项。如果我将进度条的样式设置为Marquee,我可以看到进度条,但是当我将其更改为Blocks时,我看不到进度条的进度。您应该只连接一次事件,就像在窗体的构造函数或Load()事件中一样。另外,如果您处置了BackgroundWorker(),下次单击按钮时它将如何再次运行?在MethodCall1()和MethodCall2()方法中,您是否碰巧声明了一个名为“bw”的本地BackgroundWorker()?不知道BGWorker,但通常语法
object.event+=()=>{}
被认为是泄漏的。一个好方法是首先声明变量:
var handler=()=>{}
。然后
object.event+=handler
和更高版本的
object.event-=handler