BackgroundWorker在RunWorkerCompleted上更新UI,但由于数据负载过重导致系统挂起

时间:2013-05-11 05:08:07

标签: c# .net multithreading gridview backgroundworker

我创建了一个backgroundWorker,我在RunWorkerAsync之后调用了InitializeComponent()但是经过Google搜索并通过Stack Overflow后,我才知道我无法更新UI DoWork我需要在RunWorkerCompleted

中执行此操作

所以我这样做但我的问题是我在DoWork创建了一个大数据表,以便我可以通过RunWorkerCompleted在我的网格中填充这些数据,但是在执行完所有内容后{ {1}}我的应用程序挂起几秒钟,然后在加载后恢复。

我觉得这种情况正在发生,因为我通过RunWorkerCompleted获取了大量数据,当我使用DoWork来显示它挂起的数据时。

我从数据库中获取大约50,000个数据。

如何解决此问题。除了RunWorkerCompleted之外还有什么方法可以使用并做这些事情。或者也许通过BackgroundWorker我只能进行一些调整并且效果很好。

2 个答案:

答案 0 :(得分:0)

您绝对可以从DoWork方法内部更新UI。您在评论部分中提到的错误是因为只允许拥有控件的线程对其进行修改。但是,其他线程也可以进行修改,但是需要将它包装在委托中,这使得操作是线程安全的。在DoWork方法中,无论何时想要更新控件,请按照以下步骤操作:

if (this.InvokeRequired)
{
  this.Invoke((MethodInvoker)delegate()
  {
     // Update the UI here. For example:
     // myTextBox.Text = "Hello World!";
  });
}

答案 1 :(得分:0)

抱歉,我知道这个帖子已经过时了,但我遇到了类似的问题,发现了一个不同的解决方案,不需要显式调用Invoke。这是基于ProgressChanged事件是(几乎)更新UI的事实,通过报告某些内容和类型来表明BG工作者没有被冻结或卡住。

确保您的BackgroundWorker.WorkerReportsProgress=true,并为ProgressChanged事件添加事件处理程序。

现在来了魔术,当您报告进度时,它需要一个百分比int(以及类型UserState的可选object参数),但不检查值在任何特定的范围内。因此,当我将进度报告为0100的百分比时,进度会更新(例如24%完成),但是当我发送超出该范围的数字时,其他内容" 更新":

我的DoWork方法:

...
this._BG_Worker.ReportProgress(-1);
this._BG_Worker.ReportProgress(-2, "Reading NAND");
...
this._BG_Worker.ReportProgress((int)(100.0 * a / b), string.Format("{0}/{1} bytes", a, b));
...

我的ProgressChanged事件处理程序:

if (e.ProgressPercentage>=0 && e.ProgressPercentage<=100)
    this.tsslMain.Text=string.Format("{0}% done ({1})", e.ProgressPercentage, e.UserState);
else switch (e.ProgressPercentage)
{
    case -1:
        this.lbStatus.Items.Clear();
        break;
    case -2:
        if (e.UserState!=null && e.UserState is string)
            this.lbStatus.Items.Add(e.UserState as string);
        break;
    case ...
}

所以就是这样。