C# 可观测集合的异步修改
我遇到问题,使用(Task Parallel Library)更新绑定到任务线程内的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
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();