更新 DataGrid 会导致 GUI 挂起?
Updating DataGrid causes GUI to hang?
所以我将 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());
即便如此,在 DataGrid
完全刷新之前,有一两秒钟您无法与 window 交互(看起来 GUI 正在阻塞)。我还能做些什么吗,或者这只是预期的行为?
每当 GUI 线程阻塞并且应用程序冻结时,我建议重构以使用 async/await。
本质上,您可以使用 var result = await Task.Run (() => { return MySlowMethod();});
之类的东西将繁重的工作推到后台线程上。
result
是一个 List<T>
,而 MySlowMethod
是一些慢速方法,比如一个慢速数据库调用,returns 可以复制到一个 ICollectionView
。
await
将控制权释放回 GUI 线程,因此没有任何冻结,Task.Run
在后台线程上执行繁重的工作。
我已经使用这种技术数百次了,它总是会产生一个快速、流畅、响应迅速的应用程序。
有关详细信息,google 类似 async await wpf Task.Run
。
所以我将 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());
即便如此,在 DataGrid
完全刷新之前,有一两秒钟您无法与 window 交互(看起来 GUI 正在阻塞)。我还能做些什么吗,或者这只是预期的行为?
每当 GUI 线程阻塞并且应用程序冻结时,我建议重构以使用 async/await。
本质上,您可以使用 var result = await Task.Run (() => { return MySlowMethod();});
之类的东西将繁重的工作推到后台线程上。
result
是一个 List<T>
,而 MySlowMethod
是一些慢速方法,比如一个慢速数据库调用,returns 可以复制到一个 ICollectionView
。
await
将控制权释放回 GUI 线程,因此没有任何冻结,Task.Run
在后台线程上执行繁重的工作。
我已经使用这种技术数百次了,它总是会产生一个快速、流畅、响应迅速的应用程序。
有关详细信息,google 类似 async await wpf Task.Run
。