Hel*_*ein 2 wpf multithreading dispatcher observablecollection threadpool
我有以下内容:
public ICollectionView Children
{
get
{
// Determining if the object has children may be time-consuming because of network timeouts.
// Put that in a separate thread and only show the expander (+ sign) if and when children were found
ThreadPool.QueueUserWorkItem(delegate
{
if (_objectBase.HasChildren)
{
// We cannot add to a bound variable in a non-UI thread. Queue the add operation up in the UI dispatcher.
// Only add if count is (still!) zero.
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (_children.Count == 0)
{
_children.Add(DummyChild);
HasDummyChild = true;
}
}),
System.Windows.Threading.DispatcherPriority.DataBind);
}
});
return _childrenView;
}
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好:HasChildren在后台线程中运行,后台线程使用调度程序将其结果插入到用于绑定到UI的变量中.
注意:_childrenView设置为:
_childrenView = (ListCollectionView) CollectionViewSource.GetDefaultView(_children);
Run Code Online (Sandbox Code Playgroud)
问题:
如果我从另一个ThreadPool线程调用Children属性,我会在行中得到一个NotSupportedException
_children.Add(DummyChild);
Run Code Online (Sandbox Code Playgroud)
异常文本:"此类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection."
为什么?我已经验证该代码是从Dispatcher线程执行的.
我们先遇到这个问题.问题有两个:
1-确保SourceCollection的任何更改都在主线程上(您已经完成了).
2-确保CollectionView的创建也在主线程上(如果它是在不同的线程上创建的,比如响应事件处理程序,通常情况并非如此).CollectionView期望修改在"它的"线程上,并且"它的"线程是"UI"线程.