我创建了一个backgroundWorker
,我在RunWorkerAsync
之后调用了InitializeComponent()
但是经过Google搜索并通过Stack Overflow后,我才知道我无法更新UI
DoWork
我需要在RunWorkerCompleted
所以我这样做但我的问题是我在DoWork
创建了一个大数据表,以便我可以通过RunWorkerCompleted
在我的网格中填充这些数据,但是在执行完所有内容后{ {1}}我的应用程序挂起几秒钟,然后在加载后恢复。
我觉得这种情况正在发生,因为我通过RunWorkerCompleted
获取了大量数据,当我使用DoWork
来显示它挂起的数据时。
我从数据库中获取大约50,000个数据。
如何解决此问题。除了RunWorkerCompleted
之外还有什么方法可以使用并做这些事情。或者也许通过BackgroundWorker
我只能进行一些调整并且效果很好。
答案 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
参数),但不检查值在任何特定的范围内。因此,当我将进度报告为0
到100
的百分比时,进度会更新(例如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 ...
}
所以就是这样。