在线程中填充 DataGridView

Posted

技术标签:

【中文标题】在线程中填充 DataGridView【英文标题】:Fill DataGridView in a thread 【发布时间】:2018-01-29 12:04:48 【问题描述】:

我有一个要填充数据的 DataGridView,DataGridView 中的数据是动态生成的,没有可用作绑定的数据,我使用循环并在每次迭代时填充 DataGridView 的每一行。

   private void Historique()
    
        int k = 0;
        for(int i= this.start_his; i <= this.end_his; i++)
        
            DGV.Rows.Add();
            DGV.Rows[k].Cells[0].Value = "semaine " + i;
            DGV.Rows[k].Cells[1].Value = TOOLS.GetMaxHebdo(this.annee_his, 
            i);
            k++;
        

    

功能

 TOOLS.GetMaxHebdo(this.annee_his, i);

需要一些时间来响应,所以我想在不阻塞程序的情况下填充 DataGridView 的每一行并查看一行一行的显示,有没有办法使用线程或其他方法来做到这一点?

【问题讨论】:

你是说你想让网格填充直到“end_his”的所有行......但是每一行都会有一个空白的 Cells[1].value 直到数据返回 GetMaxHebdo?! @Wheels73 感谢您的回答,是的,我希望在数据准备好时显示该行 这就是我的想法。但是如果你只想在数据准备好时显示行,为什么还需要另一个线程呢? 因为 start_his 和 end_his 之间的间隔可以更大,当间隔很大时,DGV 可能需要 2 分钟以上才能显示,否则 Visual Studio 停止执行,所以我想要一个在处理完成之前逐行显示的方式,避免长时间等待和(阻塞)程序显示DGV 有....只是不是第一个答案方式。我会看一下控件或后台工作类的调用方法。这是让进程在后台运行的理想选择,该进程会引发和事件到主线程,从而允许您更新网格。看看这里***.com/questions/29475673/… 【参考方案1】:

是的,有办法。正是这种情况是异步/等待模式的基本用法之一。

    在顶部添加using System.Threading.Tasks;。 将您的方法标记为异步:private async void Historique() 将慢速方法调用为任务:DGV.Rows[k].Cells[1].Value = await Task.Run(()=&gt;TOOLS.GetMaxHebdo(this.annee_his, i));

【讨论】:

谢谢,这就是我要找的东西,它就像一个魅力。【参考方案2】:

您可以将加载函数放在它自己的线程中,并在后台将线程运行到隐藏的 dataGridView 中,因此当程序启动时,数据已经在后台加载并保存为 dataTable 以供您随时使用 我怀疑很多人会太反感在程序启动时带有加载栏的启动画面:) 希望这会有所帮助!

【讨论】:

【参考方案3】:

这可能会对您有所帮助。通过线程调用您的函数以避免阻塞主线程和您的程序。

Thread1 = new System.Threading.Thread(Historique);
Thread1.Start();

【讨论】:

感谢您的回答,但它会生成一个异常,指出 DGV 是从另一个线程访问的 您不能从主 UI 线程以外的任何地方更新 Windows 窗体,因为它不是线程安全的。 好的,别无他法

以上是关于在线程中填充 DataGridView的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在后台线程中填充 ObjectListView?

尝试使用多线程将大型数据集填充到组合框中时,Windows 窗体冻结?

使用 sqldatareader 从另一个线程逐行填充 DataGridView

在另一个线程中填充 BufferedWaveProvider 时出现“缓冲区已满”异常

使用文本和进度条填充 DataGridView

Boost:创建对象并使用线程填充向量