我正在尝试使用后台工作程序,以便从数据库中检索大量数据,而不会拖延主线程。这看起来效果很好,除了在更新UI时,更新会冻结屏幕。相关代码如下:
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lvwTest.BeginUpdate();
lvwTest.Items.Clear();
// Populate the UI
foreach (TestItem ti in testData)
{
ListViewItem lvi = lvwTest.Items.Add(ti.Value1);
lvi.SubItems.Add(ti.Value2);
}
lvwTest.EndUpdate();
}
更新大约需要2到3秒,此时屏幕已锁定。我意识到只有主线程可以更新屏幕,但是是否可以以某种方式将这些数据加载到内存中(在后台线程或列表视图的其他实例或其他东西中)然后只显示它?我想要发生的只是程序只需刷新数据而不占用主线程中的时间。
答案 0 :(得分:1)
如果您需要将大量数据加载到UI中,则需要时间并且会阻止我们的应用。选项是智能滚动或分页。您加载所有数据,但是根据用户请求将其逐个放入。
答案 1 :(得分:1)
我建议将数据加载到内存中并使用虚拟模式 ListView
。这样,您只需根据需要创建ListViewItem
个对象。
答案 2 :(得分:0)
除了虚拟化之外,我还建议将项目分成几批,比方说100,并在每个批次中添加自己的消息。这样,在将批次添加到ListView
时,UI会更改以处理其他消息。
换句话说,所有RunWorkerCompleted
处理程序都会对第一批进行排队,以便添加单独的消息。然后,添加方法将添加项目,然后排队下一批。这将继续,直到没有更多项目要添加。此时,您将重新启用UI的相关部分(ListView
)。
答案 3 :(得分:0)
由于以上大部分都是很好的建议,但是并没有真正解决你的问题,这是另一种方法: 这将更新您的GUI并保持响应。假设你在WinForm App中?
Application.DoEvents();
this.Refresh();
然而,这并不意味着你可能不应该听从上面的想法: - )