【问题标题】:Dispatcher update of a CollectionViewSource.Source throws wrong thread exception while on same threadCollectionViewSource.Source 的调度程序更新在同一线程上引发错误的线程异常
【发布时间】:2012-04-11 19:54:12
【问题描述】:

我的模型视图中的代码摘录。

   private ObservableCollection<MessageAbstract> _messages;

    /// <summary>
    /// Gets the Messages property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public ObservableCollection<MessageAbstract> Messages
    {
        get
        {
            return _messages;
        }

        set
        {
            if (_messages == value)
            {
                return;
            }

            _messages = value;
            RaisePropertyChanged(() => Messages);
        }
    }

    private CollectionViewSource _messageView;

    public CollectionViewSource MessageView
    {
        get { return _messageView; }
        set
        {
            if (_messageView == value) return;
             _messageView = value;
            RaisePropertyChanged(() => MessageView);
        }
    }

private void MessageArrived(Message message){
   Application.Current.Dispatcher.Invoke(DispatcherPriority.Send, 
         new Action(() =>Messages.Add(message));
}

public ModelView(){
    MessageView = new CollectionViewSource{Source = Messages};
}

当我从另一个服务回调时,我仍然在 Messages.Add(message) 上收到此异常。异常消息如下。 “这种类型的 CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection。”

我认为的代码摘录。

<ListBox x:Name="MessageList" ItemsSource="{Binding MessagesView}">

我检查了 Application.Current.Dispatcher 是否与 MessageList.Dispatcher 相同,所以现在我不知道为什么我不能添加到我的视图中。我的主要目标是我有一个使用集合视图源过滤器来过滤消息列表的搜索框。

找到答案

我发现我的答案与下面答案中的第 2 点相同。我只是将我的集合的所有创建封装在 App 调度程序中。

Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,new Action(
      () => { Messages = new ObservableCollection<MessageAbstract>();
              MessageView = new CollectionViewSource { Source = Messages };
                                      ));

WPF: Accessing bound ObservableCollection fails althouth Dispatcher.BeginInvoke is used

我们之前遇到过这个问题。这个问题是双重的:

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

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

【问题讨论】:

  • 这适用于示例项目,我所做的只是注释掉 RaisePropertyChanged() 调用。但是,删除 Application.Current.Dispatcher.Invoke() 包装器会导致您引用的异常,所以我的预感是错误在其他地方,而不是在调度程序跳跃代码中。

标签: c# mvvm dispatcher collectionviewsource


【解决方案1】:

直接绑定到CollectionViewSource 时,我遇到了同样的线程问题。我通过将列表框绑定到 CollectionView 对象来解决问题。

在您的情况下,您只需将列表框声明更改为:

<ListBox x:Name="MessageList" ItemsSource="{Binding MessagesView.View}">

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多