我正在尝试使用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的尝试。
该怎么做?
答案 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
方法
加入胡椒粉和盐调味