0

別のスレッドでいくつかのデータをロードしようとしています。次に、ロードされたデータをObservableCollectionに追加し、baバインディングを介してビューを更新します。

最初に、私は次のことをしていました:

public OverviewViewModel()
{
    Thread thread = new Thread(new ThreadStart(delegate
    {
        TheTVDB theTvdb = new TheTVDB();
        foreach (TVSeries tvSeries in theTvdb.SearchSeries("Dexter"))
        {
            this.Overview.Add(tvSeries);
        }
    }));
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

これにより、次のエラーが発生しました。

このタイプのCollectionViewは、Dispatcherスレッドとは異なるスレッドからのSourceCollectionへの変更をサポートしていません。

それで、私はこのフォーラムでディスパッチャーを使用する必要があることを読んだので、ディスパッチャーにthis.Overview.Add(tvSeries)電話をかけました。

Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate
{
    this.Overview.Add(tvSeries);
},
DispatcherPriority.Normal);

これで、クラッシュしなくなりましたが、ビューは更新されません。何も起こりません。ビューは空です。メインスレッドで実行して機能をテストしました。その後、ビューが正しく更新されます。

ビューが更新されない理由と、これを修正する方法を知っている人はいますか?

アップデート

以下のアプローチは機能しているようで、すべてを非同期的に実行しているようです。これが非同期的に物事を行うための正しいアプローチであることを誰かが確認できますか?

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(delegate
{
    TheTVDB theTvdb = new TheTVDB();
    foreach (TVSeries tvSeries in theTvdb.SearchSeries("Dexter"))
    {
        this.Overview.Add(tvSeries);
    }
}),
DispatcherPriority.Background);
4

3 に答える 3

1

これは、スレッド アクティビティを処理するように WPF Dispatcher に指示する必要があるためです。

コアの詳細についてはこの記事を、追加例についてはこの記事を確認してください。

読むのは少し難しいかもしれませんが、WPF を使用している場合は、Dispatcher がどのように機能するかを学ぶ価値があります。

編集: 2 番目の記事では、実際に問題について明示的に言及しています。

最後に、ObservableCollection は追加/削除アクションの INPC イベントのみを発生させ、個々の要素の変更は発生させないことを忘れないでください。そのためには、基礎となるアイテム自体に INPC を実装する必要があります。

于 2012-11-02T09:42:35.980 に答える
0

私はスレッドセーフに行くObservableCollection<T>ので、毎回呼び出しをマーシャリングする必要はありません:)

Sasha Barber の実装をチェックしてください: ThreadSafeObservableCollection « Sacha のブログ.

于 2012-11-02T09:11:57.640 に答える
0

また、メソッドを BeginInvoke から Invoke に変更してみてください。

編集

次のように試してください:

this.Dispatcher.Invoke(new Action(()=>
{
    this.Overview.Add(tvSeries);
});
于 2012-11-02T09:21:31.733 に答える