异步修改ObservableCollections

时间:2012-04-24 06:47:15

标签: c# .net wpf binding task-parallel-library

我遇到问题,使用(任务并行库)将WPF ListView绑定更新为任务线程中的ObservableCollection<T>

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

包含的细分及其计数显示在列表框中。

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

以下是我使用的TPL呼叫:

private string _FileName;
    public string FileName
    {
      get
      {
        return _FileName;
      }
      set
      {
        _FileName = value;
        OnPropertyChanged("FileName");

        if (!String.IsNullOrEmpty(value)) 
          new Task(() => StartFile()).Start();
      }
    }

有没有人对我有任何打击?

------------ E D I T ------------------

使用TaskScheduler.FromCurrentSynchronizationContext()或Dispatcher提供的Answers没有使用Trick!

加载新版本时更改Binding是否有可能成功。

以下是我使用的Binding,在ViewModel中使用Reader Onject进行切换,并使用INotifyPropertyChanged实现GUI进行Notfied

4 个答案:

答案 0 :(得分:1)

使用调度程序访问集合:

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

答案 1 :(得分:1)

您需要在GUI线程上调用IncrementCount。

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

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

答案 2 :(得分:0)

当您在不同的线程上执行操作时,您需要使用Dispatcher.BeginInvoke对绑定到UI的集合运行更新

答案 3 :(得分:-2)

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

http://bathinenivenkatesh.blogspot.co.uk/2011/07/wpf-build-more-responsive-ui.html

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