C#后台工作人员UI更新
我正在尝试使用后台工作程序,以便在不暂停主线程的情况下从数据库检索大量数据。这似乎工作得很好,只是在更新UI时,更新会冻结屏幕。相关代码如下:C#后台工作人员UI更新,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,我正在尝试使用后台工作程序,以便在不暂停主线程的情况下从数据库检索大量数据。这似乎工作得很好,只是在更新UI时,更新会冻结屏幕。相关代码如下: private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { lvwTest.BeginUpdate(); lvwTest.Items.Clear(); /
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秒,在这段时间内屏幕被锁定。我意识到只有主线程可以更新屏幕,但是否可以以某种方式(在后台线程或listview的另一个实例中)将这些数据加载到内存中,然后显示它?我只想让程序简单地刷新数据,而不占用主线程中的时间。如果您必须将大量数据加载到UI中,这将需要时间,并且会阻塞我们的应用程序。该选项是智能滚动或分页。您可以加载所有数据,但您可以根据用户的请求将其逐个加载。我建议将数据加载到内存中,并使用虚拟模式
ListView
。这样,您只需根据需要创建ListViewItem
对象。除了虚拟化之外,我建议将这些项目分为若干批,比如说100个,并将每个批添加到自己的消息中。这样,在将批添加到列表视图
时,用户界面可以处理其他消息
换句话说,
RunWorkerCompleted
处理程序所做的就是将第一批添加到单独的消息中。然后添加方法将添加项目,然后对下一批进行排队。这将继续,直到没有更多的项目可添加为止。此时,您将重新启用UI的相关部分(“代码>列表视图”)。由于以上大部分都是很好的建议,但并不能真正解决眼前的问题,因此这里有另一种方法:
这将更新您的GUI并保持其响应性。假设您在WinForm应用程序中
Application.DoEvents();
this.Refresh();
然而,这并不意味着你不应该听上面的想法:-)这是一个WinForm应用程序-但在VB6时代,DoEvents受到了反对,因为它可能会改变事件的顺序。在C#中不是这样吗?你可能是对的,从我听到的情况来看,这仍然是一个小问题。取决于应用程序的复杂性。我已经将我上一个简单的应用程序重写到WPF,这实际上是一个非常好的框架。