BackgroundWorker未触发RunWorkerCompleted

时间:2011-10-03 12:39:48

标签: c# datagridview backgroundworker

我第一次运行我的后台工作时它正确运行 - 在后台更新数据表,然后RunWorkerCompleted将数据表设置为datagridview数据源。

如果我再次运行它,datagridview会清除并且不会更新。我无法理解为什么。

我已经验证了当我的代码命中dgvReadWrites.DataSource时,数据表包含行。

    private void btnGenerateStats_Click(object sender, EventArgs e)
    {
        dtJobReadWrite.Columns.Clear();
        dtJobReadWrite.Rows.Clear();
        dgvReadWrites.DataSource = dtJobReadWrite;

        List<Tuple<string, string>>jobs = new List<Tuple<string, string>>();

        foreach (ListViewItem job in lstJobs.SelectedItems)
        {
            jobs.Add(new Tuple<string, string>(job.Text, job.SubItems[2].Text));
        }
        BackgroundWorker bgw = new BackgroundWorker();
        bgw.WorkerReportsProgress = true;
        bgw.WorkerSupportsCancellation = true;
        bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
        bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
        pbarGenStats.Style = ProgressBarStyle.Marquee;
        pbarGenStats.MarqueeAnimationSpeed = 30;
        pbarGenStats.Visible = true;
        bgw.RunWorkerAsync(jobs);
    }


    private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bgw = sender as BackgroundWorker;
        List<Tuple<string, string>> jobs = (List<Tuple<string, string>>)e.Argument;
        GetReadWriteStats(jobs);
    }

    private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        BackgroundWorker bgw = sender as BackgroundWorker;
        bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
        bgw.DoWork -= new DoWorkEventHandler(bgw_DoWork);
        pbarGenStats.MarqueeAnimationSpeed = 0;
        pbarGenStats.Value = 0;
        pbarGenStats.Visible = false;
        dgvReadWrites.DataSource = dtJobReadWrite;
        dgvReadWrites.Visible = true;
        dgvReadWrites.Refresh();
    } 

3 个答案:

答案 0 :(得分:3)

private void btnGenerateStats_Click(object sender, EventArgs e)
{
    //...
    dgvReadWrites.DataSource = dtJobReadWrite;
    // etc...
}

这是一个问题,你正在更新BGW中的 dtJobReadWrite 。这会导致绑定网格由工作线程更新。非法的控件不是线程安全的,只能从创建它们的线程更新。通常会检查它,在调试时产生InvalidOperationException,但此检查不适用于绑定控件。

接下来出现了什么问题,你很幸运,你有一个高度可重复的死锁。更常见的不当行为是偶尔的绘画工件,只有在你不靠近时才会出现僵局。修正:

    dgvReadWrites.DataSource = null;

并在RunWorkerCompleted事件处理程序中重新绑定网格,就像您已经这样做。

答案 1 :(得分:0)

因为您取消订阅这些活动

bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.DoWork -= new DoWorkEventHandler(bgw_DoWork);

删除这些行

答案 2 :(得分:0)

为什么每次要运行它时都要创建一个新的BackgroundWorker?我想看看如果您使用BackgroundWorker的一个实例(GetReadWriteWorker或其他类似的东西),只需订阅一次事件,然后在btnGenerateStats_Click上运行该工作程序Async,此代码会发生什么。