WPF:尽管使用了 Dispatcher.BeginInvoke,但访问绑定的 ObservableCollection 仍失败

2024-01-06

我有以下内容:

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; 
 }
}

它工作得很好:HasChildren 在后台线程中运行,该线程使用调度程序将其结果插入到用于绑定到 UI 的变量中。

注意:_childrenView 设置为:

_childrenView = (ListCollectionView) CollectionViewSource.GetDefaultView(_children);

Problem:

如果我从另一个 ThreadPool 线程调用 Children 属性,我会在该行中收到 NotSupportedException

_children.Add(DummyChild);

异常文本:“这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程更改其 SourceCollection。”

Why?我已经验证该代码是从调度程序线程执行的。


我们自己就遇到过这个问题。这个问题有两个方面:

1-确保对 SourceCollection 的任何更改都在主线程上(您已经完成了)。

2-确保 CollectionView 的创建也在主线程上(如果它是在不同的线程上创建的,例如响应事件处理程序,则通常不会出现这种情况)。 CollectionView 期望修改发生在“它的”线程上,并且“它的”线程是“UI”线程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF:尽管使用了 Dispatcher.BeginInvoke,但访问绑定的 ObservableCollection 仍失败 的相关文章

随机推荐