我正在使用一个继承IEnumerable的类来检索DataType
的集合。
class DataCollector : IEnumerable<DataType>
{
public IEnumerator<DataType> GetEnumerator()
{
// this takes from 5 to 20 seconds,
// so I want it to run in a background thread.
}
}
现在只需 Name 和 Value 属性,DataType非常简单。
在我的ViewModel中:
private AsyncObservableCollection<DataType> _Data = new AsyncObservableCollection<DataType>();
我正在使用here中的AsyncObservableCollection
,因此我可以从BackgroundWorker中填充它。
ViewModel中的构造函数创建了一个BackgroundWorker,这是DoWork:
void DoWork(object sender, DoWorkEventArgs e)
{
var data = new DataCollector();
foreach (var i in data)
{
_Data.Add(i);
}
}
我得到Must create DependencySource on same Thread as the DependencyObject.
这是否意味着我需要在UI线程中创建我从DataCollector.GetEnumerator()中产生的DataType
?我怎么能绕过这个?
答案 0 :(得分:0)
为什么不等待整个事情完成,然后将项目的插入封送到UI线程?
void BackgroundWorker_Completed(ect... Im not used to work with BW so I don't know the parameters)
{
_Data.AddRange(yourdataItems);
}
修改强>:
如果要逐步填充observablecollection:
void DoWork(object sender, DoWorkEventArgs e)
{
var data = new Datacollector();
foreach (var i in data)
{
Application.Current.Dispatcher.BeginInvoke((Action)(_Data.Add(i)));
}
}
答案 1 :(得分:0)
如果您有能力升级到.NET 4.5,那么该版本的WPF改进之一就是能够在后台线程上修改集合。有关详细信息,请参阅here。
否则,在之前的版本中,您应该尝试仅通过使用Dispatcher.BeginInvoke
或Dispatcher.Invoke
或其他同步机制来修改UI线程上的集合。
答案 2 :(得分:0)
您可以使用BackGroundWorker ReportProgess传回对象(ObservableCollection)
BackgroundWorker.ReportProgress Method (Int32, Object)
一次传回100或1000行 或者只是传回前1000,然后等待完成获得总数。