2011-09-12 27 views
3

次のアプリケーションアーキテクチャを検討してください。スレッド間の同期はどうすればよいですか?

UI(表示)スレッドはViewModelを作成します。

ViewModelsコンストラクタは、ストレージからデータを取得するビジネスロジックオブジェクト(プロバイダ)を要求します。

プロバイダのDataRecievedイベントを購読してStartRetrievingData()メソッドを呼び出します。

プロバイダはStartRetrievingData()メソッド本体にバックグラウンドスレッドを作成し、取得したデータをループし、ループボディでDataRecievedイベントを発生させ、実際のデータオブジェクトをカスタムEventArgsパブリックフィールドとして渡します。

DataRecievedイベントにリンクされているViewModelメソッドが、UI要素がバインドされているobservableCollectionを更新します。

質問は以下のとおりです。

はMVVMのimplemntationようなアーキテクチャを持つOKすべてのですか?

どこの時点でUIを更新するバックグラウンドスレッドから発信された呼び出しをディスパッチするDeployment.Current.Dispatcherを呼び出すスレッド同期を行う必要がありますか?

答えて

6

個人的には、ViewModelのすべての同期要件を処理します。

ビューはViewModelに構築されている場合は、TPLは、このための素敵なメカニズムを提供:

TaskFactory uiFactory; 

public YourViewModel() 
{ 
    // Since the View handles the construction here, you'll get the proper sync. context 
    uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext()); 
} 

// In your data received event: 
private items_DataReceived(object sender, EventArgs e) 
{ 
    uiFactory.StartNew(() => 
    { 
     // update ObservableCollection here... this will happen on the UI thread 
    }); 
} 

をこのアプローチの良いところは、あなたがWPF関連の種類にプルする必要がないことです(たとえば、 Dispatcher)をViewModelレイヤーに追加すると、非常にきれいに動作します。

+0

ありがとうございました。私はおそらくこれを認めても恥ずかしいはずですが、あなたの答えの前に私はTPLが.Netに存在することに気づいていませんでした。それでも私のプロジェクトはSilverlight for Windows Phone上にあるので、私はそれを使うことはできません。ポータブルTPLは、私が見ることのできるTaskFactoryをサポートしていません。 –

+0

@Maxim:Portable TPLはこれをサポートしていますが、TaskSchedulerを取得してStartNewメソッドに明示的に渡す必要があります...残念ながら、カスタムスケジューラを使用して自分のFactoryを作ることはできません - しかし、それは現在APIには欠けている) –

関連する問題