不断报告要从后台工作人员添加到datagridview的数据会挂起UI

时间:2014-04-30 19:28:42

标签: c# datagridview backgroundworker

我有BackgroundWorker从外部源检索数据。 然后我的BackgroundWorker处理数据并使用修改后的数据更新原始来源。 我从BackgroundWorker报告回来填写DataGridView已处理的内容等。

如果它运行得好又慢,那么我的UI释放得足以让我在发生问题时使用取消按钮但是如果它运行得很快(如果数据处理的数据很少)那么UI就会忙着添加行来DataGridView,我无法及时使用取消按钮

所以...我的问题是,在保持一些UI控制以按下取消但不会进一步减慢进程的情况下,不断更新DataGridView的正确方法是什么。

3 个答案:

答案 0 :(得分:0)

当BackgroundWorker的RunWorkerCompleted事件触发时,听起来好像你正在进行所有网格更新。相反,将BackgroundWorker的WorkerReportsProgress属性设置为true,并且只要您想要传递一些新数据进入网格,就让DoWork方法调用ReportProgress

答案 1 :(得分:0)

在你的背景工作者的运行方法中,我假设你有这样的东西:

foreach (var result in database.GetAllResults()) {
    bw.ReportProgress(result);
}

您可以尝试将代码限制为每500毫秒一次更新(或者任何数字看起来效果最好),方法是将其更改为以下内容:

var buffer = new List<Result>();
var lastUpdate = DateTime.Now;
foreach (var result in database.GetAllResults()) {
    buffer.Add(result);
    if (DateTime.Now > lastUpdate.AddMilliseconds(500)) {
        bw.ReportProgress(buffer);
        buffer.Clear();
        lastUpdate = DateTime.Now;
    }
}
if (buffer.Any()) bw.ReportProgress(buffer);

当然,在您的进度处理程序中,您现在传递了List<Result>而不是单个Result,因此您还需要在其中添加for循环。

答案 2 :(得分:-1)

根据MSDN,每个ReportProgressThread.Sleep(0)应该执行此操作:

  

指定零(0)以指示应该挂起此线程以允许其他等待线程执行。