2017-12-21 7 views
-1

Async OOPで定義されたパターンに従って、2つのソースからデータを読み込むビューモデルを作成しました。しかし、私はコレクションのためにセットアップCollectionViewSourceとフィルタにしようとしたとき、私は例外Additional information: Must create DependencySource on same Thread as the DependencyObject.を取得したり、データをフィルタするとき、私は非同期ViewModelコンストラクタのデータの初期化

public NotifyTaskCompletion InitializationNotifier{ get; set; } 
    public Task Initialization => InitializationNotifier.Task; 

のviewmodelコンストラクタの定義を以下のようにThe calling thread cannot access this object because a different thread owns it.

プロパティが定義されている以下の例外を取得しますInitializationNotifierは次のように

01:

InitializationNotifier = new NotifyTaskCompletion(InitializeAsync()); 

タスクは以下のように定義されます

private async Task InitializeAsync() 
    { 
     var aDataSource = await Task.Run(() => ADataSource.Get(1, 2)); 
     var bDataSource = await Task.Run(() => new BDataSource(1, 2); 
     PrepareData(aDataSource, bDataSource); // creates List<T> for different categories 
     SetupCollections(); // Creates Observable collections from List<T> 
     SetupCVSAndFilters(); // Creates CollectionViewSource for different categories 
    } 

    private void SetupCollections() 
    { 
     AStars = new ObservableCollection<IAEntity>(m_aStars); 
     BStars = new ObservableCollection<IAEntity>(m_bStars); 
    } 
    // Setup Collectionview source and Filters 
    // Get an exception: 
    // Additional information: Must create DependencySource on same Thread as the DependencyObject. 
    private void SetupCVSAndFilters() 
    { 
     AStarsCVS = new CollectionViewSource { Source = AStars }; 
     BStarsCVS = new CollectionViewSource { Source = BStars }; 
     AStarsCVS.View.Filter = FilterCompareData; 
     BStarsCVS.View.Filter = FilterCompareData; 
    } 

ビュー/のviewmodelはAsync/Taskを使用せずにうまく動作しますが、データソースからのフェッチは、時間のかかる(PInvoke S)であり、私は別のデータを読み取る複数のタブを持っていると私は私が理解するためのポインタを感謝のですここで私は使用方法が間違っていますTask/Async

+2

ここで何が起きているのか本当に分かっていれば、同時実行ビジュアライザ(https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.ConcurrencyVisualizer2017)をインストールすることができます。単純なAPI(https://www.nuget.org/packages/ConcurrencyVisualizer/)で使用すると、コード内のセクションにマークを付け、実行されているスレッドを確認できます(https://msdn.microsoft .com/en-us/en-en/library/hh755853.aspx)。それは本当にクールです。 –

答えて

1

Task.Run()を呼び出すたびに、新しいスレッドが作成されます。例外は、あなたのスレッドが想定していない方法でお互いにアクセスしようとしていることと関係があります。あなたが提供したコードだけでどこが間違っているのか分かりませんが、WPFではスレッドはDispatcher.BeginInvoke()を使って他のスレッドのオブジェクトにアクセスできます。

あなたが探している非同期プログラミングのメリットが得られていないようです。 2つのawaitステートメントを順番に並べると、最初のタスクが完了してから2番目のタスクが開始されることになります。あなたはTask.WaitAll()がほしいと思う。

+1

なぜdownvotedですか?これは正解です。ビューモデルコンストラクタがUIスレッドから呼び出されたかどうかわからないので、何が起こっているかを示すのに十分なコードではありません。 –

+0

@swiszcz私はそれをdownvoteしなかった、私はより多くのコードを提供できたことに同意する。 view/viewmodelはタブのコンテンツで、viewmodelコンストラクタは実際にはUIスレッドから呼び出されます。 – rahul

関連する問題