2012-01-06 12 views
1

ビューモデルとして機能する2つのNotificationObjectオブジェクトがあります。最初のNotificationObjectには、特定のコントロールのビューにバインドされたプロパティが含まれています.2番目のNotificationObjectには、Threadオブジェクトを使用して別のスレッドで実行されるコードがあります。私は、最初のNotificationObjectのプロパティを2番目のNotificationObjectの実行中のコードから変更する必要があります。私はそれをしようとするとき、私は例外を取得 "呼び出しスレッドは、別のスレッドが所有しているため、このオブジェクトにアクセスできません。NotificationObjectのディスパッチャ

私は、Windowsフォームや従来のWPFのように、これらのプロパティにアクセスするために何らかのディスパッチャを使用する必要があると思いますが、Prism MVVMで行う方法はわかりません。では、どのようにして最初のNotificationObjectのプロパティを変更できますか?

答えて

4

あるスレッドで何かが作成され、別のスレッドから更新しようとしていると思いますが、WPFではこれを許可していません。オブジェクトは、作成されたスレッドからしか変更できません。

通常、すべてのオブジェクトはメインのUIスレッドで作成され、Dispatcherは非同期メッセージをUIスレッドに渡してこれらのオブジェクトを更新します。しかし、メインUIスレッドを使用する必要があるオブジェクトのプロパティを更新するために、バックグラウンドスレッドで重い処理を実行することはできます。

例えば、このようなものは動作します:

MyNotificationObject obj = new MyNotificationObject; 
obj.Items = MethodThatRunsOnBackgroundThread(); 

List<SomeObject> MethodThatRunsOnBackgroundThread() 
{ 
    var list = new List<SomeObject>(); 
    // Do Work 
    Return list; 
} 

これはないだろうが。それは更新するためのメッセージを送信しているので、ここで

MyNotificationObject obj = new MyNotificationObject; 
MethodThatRunsOnBackgroundThread(obj); 

void MethodThatRunsOnBackgroundThread() 
{ 
    var list = new List<SomeObject>(); 
    // Do Work 

    // This won't work since obj was created on UI thread 
    obj.Items = List<SomeObject>; 
} 

は、作品別の例でありますオブジェクトを作成したUIスレッドに渡します。

MyNotificationObject obj = new MyNotificationObject; 
MethodThatRunsOnBackgroundThread(obj); 

void MethodThatRunsOnBackgroundThread() 
{ 
    var list = new List<SomeObject>(); 

    // Load List 

    Application.Current.Dispatcher.BeginInvoke(DispatherPriority.Background, 
     new Action(delegate { 
      obj.Items = list; 
     })); 
} 
+0

あなたの努力に感謝します、Rachel、しかし私はすでにこのアプローチを試みました。 Dispatcher.CurrentDispatcher.Invokeは機能しません。私はBas Bの答えに対するコメントとして書きました。 –

+1

@ Bogdan0x400申し訳ありませんが、その構文は間違っています。 'Dispatcher.CurrentDispatcher'は現在のスレッドのディスパッチャを返します。バックグラウンドスレッドから呼び出すと、バックグラウンドスレッドのディスパッチャを返します。 UIスレッドのディスパッチャを取得するにはUIから呼び出すか、 'Application.Current.Dispatcher'のようなものを使用する必要があります。 'App.Current.Dispatcher'は、WPFプロジェクトの起動アプリケーションがデフォルトで' App'と呼ばれるため、通常見られる構文です。あなたの ''が別のものと呼ばれている場合は、代わりにそれを使用しなければなりません – Rachel

0

Application.Current.Dispatcherはかなりこれはありがたいことに、もはや必要ではないだろう、.NET 4.5で最も簡単な解決策..

です。

+0

少なくとも私のプロジェクトでは、Application.Current.Dispatcherのようなものはありません。 Dispatcher.CurrentDispatcher.Invokeを意味しましたか?私はすでに試しましたが、同じエラーが発生しました。 –

0

モデルビューのNotificationObjectではなく、ビューのUserControlオブジェクトでDispatcherを探す必要がありました。私は、MVVMのモデルビューからビューを参照するのは良くないと思うが、まだもっと良い解決策は見つけられていない。

関連する問題