更新DataGrid会导致GUI挂起
本文关键字:GUI 挂起 DataGrid 更新 | 更新日期: 2023-09-27 17:51:05
所以我将DataGrid
绑定到ICollectionView
。我将虚拟化设置为True。
<DataGrid
EnableColumnVirtualization="True" EnableRowVirtualization="True"
IsReadOnly="True"
ItemsSource="{Binding ImportRecords, IsAsync=True}"
Name="ImportRecordsView">
我通过TPL创建了一个任务来填充ObservableCollection(大概不在GUI线程上)。
Task<ObservableCollection<myClass>> task = Task.Factory.StartNew(
() =>
{
var records = new ObservableCollection<myClass>();
for(int i = 0; i < 10000; i++)
{
records.Add(new myClass());
}
return records;
});
我使用continue with,它将在GUI线程上恢复,并将结果带入视图。我甚至使用了DeferRefresh()方法。
task.ContinueWith( (e) => {
using (ImportRecordsView.Items.DeferRefresh())
{
CollectionViewSource cv = new CollectionViewSource() { Source = e.Result };
ImportRecords = cv.View;
}
}, System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());
即使在所有这些之后,有一秒钟或两秒钟,你不能与窗口交互(看起来像GUI阻塞),直到DataGrid
完全刷新。我还能做些什么吗,还是这只是预期行为?
每当GUI线程阻塞和应用程序冻结时,我建议重构使用async/await。
基本上,您可以使用var result = await Task.Run (() => { return MySlowMethod();});
之类的东西将繁重的工作推到后台线程上。
result
是一个List<T>
,而MySlowMethod
是一个慢的方法,就像一个慢的数据库调用,它返回一些可以复制到ICollectionView
的东西。
await
将控制释放回GUI线程,所以没有冻结,Task.Run
在后台线程上执行繁重的工作。
我已经使用这种技术数百次了,它总是产生一个快速,流畅,响应迅速的应用程序。
更多信息,谷歌async await wpf Task.Run
。