Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BackgroundWorker在RunWorkerCompleted上更新UI,但由于数据负载过大,系统挂起_C#_.net_Multithreading_Gridview_Backgroundworker - Fatal编程技术网

C# BackgroundWorker在RunWorkerCompleted上更新UI,但由于数据负载过大,系统挂起

C# BackgroundWorker在RunWorkerCompleted上更新UI,但由于数据负载过大,系统挂起,c#,.net,multithreading,gridview,backgroundworker,C#,.net,Multithreading,Gridview,Backgroundworker,我创建了一个backgroundWorker,在InitializeComponent()之后调用RunWorkerAsync,但是通过谷歌搜索和堆栈溢出,我知道我无法通过DoWork更新UI,我需要在RunWorkerCompleted中执行此操作 所以我这么做了,但我的问题是我在DoWork中创建了一个大数据表,这样我就可以通过RunWorkerCompleted将数据填充到我的网格中,但在完成所有操作后,当它转到RunWorkerCompleted时,我的应用程序会挂起几秒钟,然后在加载后

我创建了一个
backgroundWorker
,在
InitializeComponent()
之后调用
RunWorkerAsync
,但是通过谷歌搜索和堆栈溢出,我知道我无法通过
DoWork
更新
UI
,我需要在
RunWorkerCompleted
中执行此操作

所以我这么做了,但我的问题是我在
DoWork
中创建了一个大数据表,这样我就可以通过
RunWorkerCompleted
将数据填充到我的网格中,但在完成所有操作后,当它转到
RunWorkerCompleted
时,我的应用程序会挂起几秒钟,然后在加载后恢复

我觉得这是因为我正在通过
DoWork
获取大量数据,并且当我使用
RunWorkerCompleted
显示数据时,它会挂起

我有大约50000个数据,我正在从数据库中获取


如何解决这个问题。除了
BackgroundWorker
之外,我还有什么方法可以使用和做这些事情吗。或者通过
BackgroundWorker
只有我可以做一些调整,而且效果很好。

您可以从
DoWork
方法内部更新UI。您在comments部分所说的错误是因为只有拥有控件的线程才允许修改它。但是,其他线程也可以进行修改,但它们需要将其包装在一个委托中,从而使操作线程安全。在
DoWork
方法中,无论何时要更新控件,请执行以下步骤:

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

抱歉,我知道这个线程很旧,但我遇到了类似的问题,并找到了一个不需要显式调用
Invoke
的不同解决方案。这是基于这样一个事实,即
ProgressChanged
事件(基本上)通过报告某种指示BG工作程序未冻结或卡住的内容来更新UI

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

现在,神奇的是,当您报告进度时,它会将百分比作为
int
(以及类型为
object
的可选
UserState
参数),但不会检查值是否在任何特定范围内。因此,当我报告从
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));
...
My
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 ...
}

if(e.ProgressPercentage>=0&&e.ProgressPercentage为什么不能从
DoWork
更新UI?@programmer93就是这样。正如我所做的那样,它说的
非法跨线程操作:控件“myTextBox”是从创建它的线程以外的线程访问的。
我浏览网页,知道UI更新是不允许的从
DoWork
我相信这仍然会阻塞UI线程。如果他将数据添加到较小的块中,可能会不那么明显。不过,我可能只会将记录的数量限制在一个更易于管理的数字。是的,添加较小的数据块是关键。我不知道他使用的数据类型是什么,只是一块块的let’say 100应该可以做到这一点。在任何情况下,它仍然比在工作人员完成时一次向UI提供所有数据要好。@Ginosaji这不应该阻止。Invoke将确保您使用拥有控件窗口句柄的线程。我在backgroundworker Dowork函数中使用它时,它仍然冻结。有什么帮助吗?