将项目添加到ObservableCollection <t>,而不会阻止UI

时间:2018-07-23 11:27:27

标签: c# observablecollection

我正在尝试使用ObservableCollection<ProductSpecification>从数据库表向SqlReader添加项目。这是代码:

public void GetProductSpecification()
{
    ProductSpecificationList.Clear();

    using (var connect = Connection.Connect())
    {
        string query = "select * from ut_kst_specyfikacje_indeksow_test";

        using (SqlCommand cmd = new SqlCommand(query, connect))
        {
            try
            {
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        ProductSpecificationList.Add(new ProductSpecification()
                        {
                            //Here I am setting values of fields from reader[xx]. No parsing/converting errors in here.
                            //Also tried Dispatcher in here, but it throws exception "Invalid attempt to call MetaData while reader is closed"
                        });
                    }

                }

            }
            catch (SqlException e)
            {
                NLogger.logger.Error(e.Message);
            }
        }
    }
}

在绑定到button的ICommand命令之一中调用了此方法。当我单击此按钮时,UI冻结大约10秒钟(ut_kst_specyfikacje_indeksow_test中有45000条记录)。我认为这有点慢,说实话,我希望大约2秒钟。

据我所知,ObservableCollection已绑定到UI,无法从UI Thread之外的其他线程进行更新。我尝试使用Dispatcher,但发生异常:

  

在阅读器关闭时,无效的调用MetaData的尝试。

该怎么做?

1 个答案:

答案 0 :(得分:3)

问题是您为ObservableCollection中的每一项添加都发出了一条通知。这对于45000件商品来说效果不佳

请注意,有很多解决方案,但是由于您每次都要清除它,因此只需创建一个新列表并一次性更新即可。实际上,除非您要添加和删除项目,否则您甚至都不需要ObservableCollection。但是,这里有一个示例,可以一口气进行更新并改善您的用户界面

var list = new List<ProductSpecification>();

while (reader.Read())
{
    list.Add(new ProductSpecification()
                            {
                                //Here I am setting values of fields from reader[xx]. No parsing/converting errors in here.
                                //Also tried Dispatcher in here, but it throws exception "Invalid attempt to call MetaData while reader is closed"
                            });
} 

ProductSpecificationList = new ObservableCollection<ProductSpecification>(list);

注意:假设ProductSpecificationList引发了属性更改事件

还可以考虑制作全部async Task,并在async和类似的

中使用ExecuteReaderAsync方法

加入胡椒粉和盐调味