C# 可观测集合的异步修改

C# 可观测集合的异步修改,c#,.net,wpf,binding,task-parallel-library,C#,.net,Wpf,Binding,Task Parallel Library,我遇到问题,使用(Task Parallel Library)更新绑定到任务线程内的ObservableCollection的WPF ListView 我有一个小工具读取文件,并显示每个段的计数(一行的前三个字母) 包含的段及其计数显示在列表框中 Wenn我最初加载一个文件,一切正常,我看到GUI正在计算段数。 我的程序允许切换到另一个文件,如果我这样做(使用完全相同的代码),它会失败,出现以下异常 此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其Sourc

我遇到问题,使用(Task Parallel Library)更新绑定到任务线程内的
ObservableCollection
的WPF ListView

我有一个小工具读取文件,并显示每个段的计数(一行的前三个字母)

包含的段及其计数显示在列表框中

Wenn我最初加载一个文件,一切正常,我看到GUI正在计算段数。 我的程序允许切换到另一个文件,如果我这样做(使用完全相同的代码),它会失败,出现以下异常

此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection

下面是失败的代码

public class SegementLineCollection : ObservableCollection<SegmentLine>
  {
    public void IncrementCount(string Segment)
    {
      Segment = Segment.ToUpper();

      SegmentLine line;
      if (this.Select(x => x.SegmentName).Contains(Segment))
      {
        line = this.Where(x => x.SegmentName == Segment).FirstOrDefault();
      }
      else
      {
        line = new SegmentLine();
        line.SegmentName = Segment;

        this.Add(line); // <--- At this point comes the Exception
      }

      line.Count++;
    }
  }
有人给我打过电话吗

------------爱迪特------------------

使用TaskScheduler.FromCurrentSynchronizationContext()或Dispatcher提供的答案没有起作用

是否有可能在加载新文件时更改绑定就可以做到这一点


这是我使用的绑定,Reader对象在ViewModel中切换,当您在不同的线程上操作时,需要使用
Dispatcher。要在绑定到
UI

的集合上运行更新,请使用Dispatcher访问集合:

if (Dispatcher.CurrentDispatcher.CheckAccess())
  this.Add(...)
else
  Dispatcher.CurrentDispatcher.Invoke(() => this.Add(...));

您需要在GUI线程上调用IncrementCount

使用TPL,您可以在任务或继续中使用
TaskScheduler.fromCurrentSynchronizationContext()

var task = new Task<string>(() => { return "segment"; })
var task2 = task.ContinueWith(t => IncrementCount(t.Result),
                              TaskScheduler.FromCurrentSynchroniztionContext());
task.Start();
var task=新任务(()=>{return“segment”;})
var task2=task.ContinueWith(t=>IncrementCount(t.Result),
TaskScheduler.fromCurrentSynchronizationContext());
task.Start();

我在下面的博客中找到了解决此类问题的方法


它得到了详细的解释和代码片段…

replice of您是否阅读了异常消息?斯维克,他读过,但他不是在问问题,而是在问解决办法。顺便说一句,为什么这是第一次?这不应该导致同样的异常吗?@svick:当然,我读了异常消息,发现这是线程问题。如果我知道答案,我不会问。@sebastianmehler:你是什么意思?帮助我解决了我的问题。谢谢
var task = new Task<string>(() => { return "segment"; })
var task2 = task.ContinueWith(t => IncrementCount(t.Result),
                              TaskScheduler.FromCurrentSynchroniztionContext());
task.Start();