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

Posted

技术标签:

【中文标题】尝试使用多线程将大型数据集填充到组合框中时,Windows 窗体冻结?【英文标题】:Windows form freezing when trying to use multithreading to populate large data set into a combox? 【发布时间】:2019-11-13 08:18:03 【问题描述】:

我正在尝试将大约 3000 个单词的列表填充到 Windows 窗体组合框下拉菜单中。在一个迭代循环中完成它需要很长时间,所以我决定使用多线程让一个线程在列表的三分之一上做同样的工作。它运行得更快,但我注意到它在线程运行时冻结了很多。我不确定这是锁定问题还是填充组合框项目列表需要很长时间。

我尝试过使用方法调用程序,但我觉得在这种情况下我使用它们是错误的。

我已经启动了这些线程:

Thread threadmid = new Thread(splitMidThird);
Thread threadtop = new Thread(splitTopThird);

threadmid.Start();
threadtop.Start();

private void splitMidThird()

  int thirds = totalPartNumber.Count() / 3;
  if (PartNumber_Text.InvokeRequired)
  
    PartNumber_Text.BeginInvoke(new MethodInvoker(delegate
    
      for (int index = thirds; index <= thirds * 2; index++)
                                      
        PartNumber_Text.Items.Add(totalPartNumber.ElementAt(index));
      
    ));
  
  return;


private void splitTopThird()

  int thirds = totalPartNumber.Count() / 3;
  if (PartNumber_Text.InvokeRequired)
  
    PartNumber_Text.BeginInvoke(new MethodInvoker(delegate
    
      for (int index = thirds * 2; index <= totalPartNumber.Count() - 1; index++I)
                              
        PartNumber_Text.Items.Add(totalPartNumber.ElementAt(index));
      
    ));
  
  return;

当我尝试这个时,表单会冻结。

【问题讨论】:

你有没有尝试过简单的方法,只使用单词列表作为数据源? 数据源是否与组合框项目列表相同?我没有尝试从数据库连接。 你试过AddRange()吗?比如:PartNumber_Text.Items.AddRange(totalPartNumber.ToArray()); 只有一个 UI 线程,所以额外的线程毫无意义。当您调用 BeginInvoke 时,即“在拥有控件的线程上运行它”。拥有控件的线程是唯一的 UI 线程,因此您的线程只需启动并在主 UI 线程本身上按顺序运行... @Idle_Mind 谢谢你工作得这么快。 【参考方案1】:

使用AddRange() 方法:

当使用此方法将项目添加到集合中时,您不需要 调用 BeginUpdate 和 EndUpdate 方法来优化性能。

类似:

PartNumber_Text.Items.AddRange(totalPartNumber.ToArray());

【讨论】:

以上是关于尝试使用多线程将大型数据集填充到组合框中时,Windows 窗体冻结?的主要内容,如果未能解决你的问题,请参考以下文章

将大型数据集缓存到 spark 内存中时“超出 GC 开销限制”(通过 sparklyr 和 RStudio)

使用C#使用数据集头填充组合框

在 Datalab 中使用大型数据集进行数据准备和描述

Excel当下拉框选中时自动填充其他框

如何将长文本文件字段放入列表框?

在 C# 中填充组合框的最快方法是啥? [关闭]