我在带线程的DataView上正确使用了RowFilter吗
本文关键字:RowFilter 线程 DataView | 更新日期: 2023-09-27 18:26:39
EDIT:我使用的是VS2008,.NET 3.5
我有一个DataTable,它被填充在DataView中并传递到CollectionView中。
DataTable newLeadTable = new DataTable();
myConnection.Open();
dbAdpater.Fill(newLeadTable);
this.LeadDataView = new DataView(newLeadTable);
this.LeadsCollectionView =
CollectionViewSource.GetDefaultView(this.LeadDataView);
然后,用于显示数据的DataGrid绑定到this.LeadsCollectionView
用户在视图中输入筛选文本后,ViewModel将执行此方法在DataView:上设置筛选字符串
private void SetLeadListFilter(string LeadFilterStr)
{
this.LeadDataView.RowFilter = filterString;
}
它工作得很好,我可以看到DataGrid显示了正确的过滤DataRow。
但我想给一些UI体验,添加一个繁忙的指示器。所以我把上面的代码放入一个线程:
this.IsBusy = true;
Thread filterDataThread= new Thread(new ThreadStart(() =>
{
this.LeadDataView.RowFilter = filterString;
this.IsBusy = false;
}));
filterDataThread.Start();
现在很奇怪,我可以看到代码被运行,过滤器被设置。但是DataGrid并没有过滤掉这些行!
所以现在我修改了这个方法,再次将DataView重新分配到CollectionView中:
this.IsBusy = true;
Thread filterDataThread= new Thread(new ThreadStart(() =>
{
this.LeadDataView.RowFilter = filterString;
this.LeadsCollectionView = CollectionViewSource.GetDefaultView(this.LeadDataView); //Added this
this.IsBusy = false;
}));
filterDataThread.Start();
现在它工作了!数据正在DataGrid上正确筛选!
那么,当我使用线程时,为什么会发生这种情况呢?这是在线程中使用DataFilter的正确方法吗?
不能肯定,但据我所知,您使用
CollectionViewSource.GetDefaultView(this.LeadDataView);
以获取DataGrid的数据源。答案是基于这个假设
所以,如果你要在filterDataThread
之外调用这个方法,就像这样:
this.IsBusy = true;
Thread filterDataThread= new Thread(new ThreadStart(() =>
{
this.LeadDataView.RowFilter = filterString;
this.IsBusy = false;
}));
filterDataThread.Start();
this.LeadsCollectionView =
CollectionViewSource.GetDefaultView(this.LeadDataView);
那么带有GetDefaultView
的代码可能会在线程工作之前运行——MainThread
和filterDataThread
之间会有竞争,MainThread
获胜,而DataGrid
不会过滤数据。
但如果你要使用你提供的代码:
this.IsBusy = true;
Thread filterDataThread = new Thread(new ThreadStart(() =>
{
this.LeadDataView.RowFilter = filterString;
this.LeadsCollectionView =
CollectionViewSource.GetDefaultView(this.LeadDataView); //Added this
this.IsBusy = false;
}));
filterDataThread.Start();
过滤将及时开始
所以答案是:
是的,你做的过滤是正确的。但在后台线程中执行操作时,您应该添加代码来处理错误,这样您的应用程序就不会永远是Busy
。
此外,您应该检查对filterString
的安全访问——如果您要启动两个或多个线程进行筛选,则会出现另一场结果不可预测的竞争。