Backgroundworker ReportProgress只触发一次?

时间:2013-06-18 10:51:12

标签: c# progress-bar backgroundworker

我的Processbar1ReportProgress分别只触发一次,原因是什么?

我第一次点击按钮,一切都按预期工作。除了ProgressBar1

之外,所有进一步的点击仍然有效

我可以在调试器中看到progressBar1.Value在第一次运行中获得了预期的值,所有进一步的运行progressBar1.Value总是包含“0”。

最奇怪的是它运行foreach-loop,所有内容都被执行,即使b.ReportProgress(i * 100 / x)中的值都正确,但没有成功的进度条。
i =当前循环次数
 x =总循环次数

以下是我的代码片段:

BackgroundWorker b = new BackgroundWorker();

    public Form()
    {
        InitializeComponent();

        b.WorkerReportsProgress = true;
        b.DoWork += new DoWorkEventHandler(b_DoWork);
        b.RunWorkerCompleted += new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
        b.ProgressChanged += new ProgressChangedEventHandler(b_ProgressChanged);
    }

    void b_DoWork(object sender, DoWorkEventArgs e)
    {
        int i = 0;
        int x = xxx.MaxValue;
        foreach (var item in collection)
        {
            //... somecode   ...(item);
            b.ReportProgress(i * 100 / x);
            i++;
        }
        //... somecode
        e.Result = dt;
    }

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

    void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        GridView.DataSource = e.Result;
        GridView.Update();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        b.RunWorkerAsync();
    }

修改:

    private void btnClearGrid_Click(object sender, EventArgs e)
    {
        dt.Clear();
        GridView.DataSource = dt;
        GridView.Update();
    }

我发现了问题..
问题是我在运行Backgroundworker之前尝试清除Gridview,这个btnClearGrid - Click-Event,其中包含GridView.DataSource = dt;将一个额外的数据源绑定到网格(我认为是这样),而不是清除网格。

    private void btnClearGrid_Click(object sender, EventArgs e)
    {
        dt.Clear();
        GridView.DataSource = null;
    }

2 个答案:

答案 0 :(得分:1)

我遇到了问题,这与更新ProgressBar的速度有关,我通过在DoWork方法中添加显式线程休眠来解决这个问题。 IE:

 b.ReportProgress(i * 100 / x);
 Thread.Sleep(50);

(在这部分中检查50毫秒与正在进行的实际工作相比并不多;如果是报告进度并且偶尔只睡一次)

答案 1 :(得分:0)

尝试在点击之间重置进度条:

private void button1_Click(object sender, EventArgs e)
{
    progressBar1.Value = 0;
    b.RunWorkerAsync();
}