更改ObservableCollection / CollectionViewSource时UI冻结

时间:2013-09-10 19:01:24

标签: c# wpf mvvm task async-await

我有一个datagrid,它接收超过100,000行的更新,这些行绑定到一个CollectionViewSource.View,其源是一个ObservableCollection。如果我尝试在当前设置中更新,当我将新行添加到ObservableCollection时,UI会完全冻结。为了解决这个问题,我在将行添加到ObservableCollection之前设置了CollectionViewSource.Source = null,这使得它可以正常工作。唯一的问题是,一旦我为第一次加载执行此操作,下一次加载仍会出现UI冻结问题。 这是代码。

public CollectionViewSource ViewSource { get; set; }
private ObservableCollection<ScreenerRow> internalRows = new ObservableCollection<ScreenerRow>();


private async Task Search()
{
    internalRows.Clear();
    ViewSource.Source = null;
    var data = await Task.Run(() =>
    {
        return DoStuff();
    });
    if (data == null) return;
    foreach (ScreenerRow sRow in data)
    {
        //freezes in here on second run
        internalRows.Add(sRow);
    }
    ViewSource.Source = internalRows;
}

只是想知道是否有其他人遇到过这个问题,或者看到我这样做的问题。 谢谢你的帮助。

编辑:将我的ObservableCollection更改为List可以使其正常工作。

//private ObservableCollection<ScreenerRow> internalRows = new ObservableCollection<ScreenerRow>();
private List<ScreenerRow> internalRows = new List<ScreenerRow>();

1 个答案:

答案 0 :(得分:0)

我从你的编辑中看出这可能不是这种情况,但是如果你确实需要集合是可观察的,那么你也可以使用CollectionViewSource.DeferRefresh()方法来阻止UI每次更改后更新:

private async Task Search()
{
    internalRows.Clear();
    using(ViewSource.DeferRefresh())
    {
        var data = await Task.Run(() => GetSearchResults());

        if (data == null) return;

        foreach (ScreenerRow sRow in data)
        {                
            internalRows.Add(sRow);
        }           
    }
}

并确保您在控件上正确设置了虚拟化模式。