3

ObservableCollection<T>問題があります。 (タスク並列ライブラリ)を使用して、タスクスレッド内のにバインドされたWPFListViewを更新します。

エディファクトファイルを読み取り、各セグメントの数(行の最初の3文字)を表示する小さなツールがあります。

含まれているセグメントとそのカウントがリストボックスに表示されます。

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();
      }
    }

誰かが私にヒットしたことはありますか?

- - - - - - 編集 - - - - - - - - -

TaskScheduler.FromCurrentSynchronizationContext()またはDispatcherを使用して提供された回答は、トリックを実行しませんでした。

新しいものをロードするときにバインディングを変更することでうまくいく可能性はありますか?

これが私が使用するバインディングであり、Reader OnjectはViewModelで切り替えられ、GUIはINotifyPropertyChanged実装で通知されます

4

4 に答える 4

1

ディスパッチャを使用してコレクションにアクセスします。

if (Dispatcher.CurrentDispatcher.CheckAccess())
  this.Add(...)
else
  Dispatcher.CurrentDispatcher.Invoke(() => this.Add(...));
于 2012-04-24T06:56:15.567 に答える
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();
于 2012-04-24T07:01:45.093 に答える
0

別のスレッドで動作しているためDispatcher.BeginInvoke、にバインドされたコレクションの更新を実行するために使用する必要がありますUI

于 2012-04-24T06:55:50.377 に答える
-2

この種の問題の解決策は、次のブログにあります..

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

詳細な説明とコードスニペットがありました...

于 2012-04-24T09:41:51.707 に答える