更新DataGrid会导致GUI挂起吗?

时间:2015-05-28 20:41:42

标签: c# wpf datagrid .net-4.0

所以我将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;

    });

我使用一个继续,它将在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完全刷新之前,还有一两秒钟您无法与窗口交互(看起来像GUI正在阻塞)。还有什么我可以做的,或者这只是预期的行为?

1 个答案:

答案 0 :(得分:0)

每当GUI线程阻塞并且应用程序冻结时,我建议重构以使用async / await。

基本上,您可以使用类似var result = await Task.Run (() => { return MySlowMethod();});之类的东西将重物推到背景线程上。

resultList<T>,而MySlowMethod是一种慢速方法,就像一个慢速数据库调用,它返回一些可以复制到ICollectionView的内容。

await释放控制回GUI线程,因此没有任何冻结,Task.Run在后​​台线程上执行繁重的工作。

我已经使用了这种技术数百次,它总能产生一个快速,流畅,响应迅速的应用程序。

有关详细信息,请使用类似async await wpf Task.Run的内容。