c# - 检查 Dispatcher.CurrentDispatcher.Thread.ManagedThreadId 后的 CollectionView NotSupportedException

标签 c# wpf multithreading .net-4.0 task-parallel-library

我正在尝试使用 Task.Factory.StartNew() 运行后台操作。部分后台操作更新保存在 ObservableCollection 中的对象。我正在使用从 ObservableCollection 派生的自定义类来触发 OnCollectionChanged() 当集合中的一个对象的属性发生更改时(请参阅 https://stackoverflow.com/a/5256827/62072 )。如果有 CollectionView 绑定(bind)到 ObservableCollection,那么我会得到一个异常:

System.NotSupportedException: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

我试图避免此异常,因此我添加了一些代码,以便仅在 UI 线程上运行时才触发 OnCollectionChanged()。但不知何故我仍然得到异常(exception)..

这是我的 ItemPropertyChanged() 方法:

void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    var a = new NotifyCollectionChangedEventArgs(
        NotifyCollectionChangedAction.Reset);

    if (Thread.CurrentThread.ManagedThreadId
         == Dispatcher.CurrentDispatcher.Thread.ManagedThreadId)
    {
        OnCollectionChanged(a);
    }
}

这里是完整的异常(exception):

System.AggregateException was unhandled
  Message=A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
  Source=mscorlib
  StackTrace:
       at System.Threading.Tasks.TaskExceptionHolder.Finalize()
       Message=This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
      InnerException: System.NotSupportedException
           Source=PresentationFramework
           StackTrace:
                at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
                at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
                at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
                at SourceLog.Model.TrulyObservableCollection`1.ItemPropertyChanged(Object sender, PropertyChangedEventArgs e) in C:\github.com\tomhunter-gh\SourceLog\SourceLog.Model\TrulyObservableCollection.cs:line 41
                at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
                at SourceLog.Model.LogEntry.OnPropertyChanged(String property) in C:\github.com\tomhunter-gh\SourceLog\SourceLog.Model\LogEntry.cs:line 44
                at SourceLog.Model.LogEntry.set_Read(Boolean value) in C:\github.com\tomhunter-gh\SourceLog\SourceLog.Model\LogEntry.cs:line 28
                at SourceLog.Model.LogEntry.<MarkAsReadAndSave>b__0() in C:\github.com\tomhunter-gh\SourceLog\SourceLog.Model\LogEntry.cs:line 53
                at System.Threading.Tasks.Task.InnerInvoke()
                at System.Threading.Tasks.Task.Execute()
           InnerException: 

为什么异常会提示我不在 Dispatcher 线程上,而我已明确检查过我在 Dispatcher 线程上?

最佳答案

Dispatcher.CurrentDispatcher 与 UI 线程无关,正如该属性的名称所暗示的那样,它为您提供了当前线程的调度程序。因此,您创建了一个始终返回 true 的检查。使用 Application.Current.Dispatcher,也可以在所述调度程序上调用它而不是忽略更改。

关于c# - 检查 Dispatcher.CurrentDispatcher.Thread.ManagedThreadId 后的 CollectionView NotSupportedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12110740/

相关文章:

java - C# 序列化器/反序列化器与 java 中的 XStream 具有相同的功能

wpf - 使用 Caliburn.Micro 进行验证

ios - 在执行之前停止后台执行

multithreading - 多线程渲染 D3D/OpenGL/Whatever

c# - 无法在 datagridview 中的单元格离开事件中获取当前单元格值

c# - 设置一个c#正则表达式

c# - 在 Razor 中使用静态变量

wpf - 使用参数将 WPF GridViewColumn 绑定(bind)到方法

c# - 以编程方式在按钮内添加图像

multithreading - 堆栈内存分配