質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

並列処理

複数の計算が同時に実行される手法

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

8154閲覧

MVVMと並列プログラミングのすり合わせ方について知りたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

並列処理

複数の計算が同時に実行される手法

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

2クリップ

投稿2015/08/27 07:20

WPFでMVVMで設計しています。
GUI以外の部分はなるべく裏で行いたいと思い、Model,ViewModelを別スレッドで実行したいと考えています。
この場合、どの辺りから別スレッドの切り替えをしたらよいか悩んでいます。

操作から反応までの流れを以下のように考えてみました。

GUI(window)->ICommand->ViewModel(Model)->INotityPropertyChanged->GUI(Window)

ICommand~INotifyPropertyChangedまでの間を別スレッドとして走らせています。
この時INotifyPropertyChangedの発行が裏スレッドで行われるので、UIスレッドで実行する必要があります。
この切り替えをViewModel側で行うか、GUIで行うかというところで悩んでいます。

ViewModel側で行う場合
○Taskの管理をViewModel内部で完結することが出来る
×Modelの階層が複数ある場合(例えば子供にもINotifyPropertyChangedがあり、連動したい場合)、全部の通知に介入しないとならない
→TaskScheduler(UIスレッド)をModelに渡す必要が出てくる

C#

1//ViewModelのイベント発行側 2public string text; 3public string Text 4{ 5 get 6 { 7 return text; 8 } 9 set 10 { 11 text = value; 12 Task.Factory.StartNew(() => 13 { 14 PropertyChanged(this, new PropertyChangedEventArgs(nameof(Text)); 15 }, CancellationToken.None, TaskCreationOptions.None, uiThread); //UIスレッドで実行 16 } 17} 18

GUI(Window)側で行う場合
○ViewModel側にTaskSchedulerなどの不要情報が入らない
○イベント通知がシンプルに渡せる
×Window側のイベントハンドラがどのスレッドが分かりにくくなる

C#

1//Windowのイベントハンドラ 2private void ViewModel_PropertyChanged(object sender, ProperyChangedEventArgs e) 3{ 4 Task.Factory.StartNew(() => 5 { 6 //結果の描画など 7 }, CancellationToken.None, TaskCreationOptions.None, uiThread); //UIスレッドで実行 8}

イマイチどちらもスッキリしません。
もしかしたらスレッドの実行のさせ方に問題があるのかもしれません。
いい方法などありましたらご教示ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tak1wa

2015/08/27 07:45

View-ViewModel-Modelそれぞれの階層にどのような役割を当てていますか。 記載からするとModelにINotifiPropertyChangedを実装し、Modelインスタンスを直接バインドしていたりしますか?(実質ViewModelはModelプロパティの引き渡し役)
退会済みユーザー

退会済みユーザー

2015/08/27 07:52 編集

Modelは複数あり、子供を持ちイベントを出してくるものもあります。 イベントを出さないものについてはViewModelがまとめて出していますが、Modelの子供が変更されたものはViewModelのプロパティ→Modelのイベント→GUIにバインドしています。 もしかしたらModelのリスト形式の子供のプロパティの変動をどうバインドするかという話かもしれません。
guest

回答1

0

ベストアンサー

こんにちは。

これはMVVMの実装方針が人により異なるのでケースバイケースな気がします。
私は通常Modelはビジネスロジック部分として独立させているので、ViewModel側はModelの処理呼び出しと、完了イベントの補足などを行い、適宜UI用のDataObjectを生成の上、View側へバインドさせています。

つまり、ViewとViewModelはUIスレッドですが、Modelのどの処理がUIスレッドのままで、どの処理がバックグラウンドスレッドなのかはModelに一任させています。
つまりINotifyPropertyCHangedの実装はViewModel層のクラスのみとしています。
Model側でINotifyPropertyChangedを実装するケースもありますが、Viewに直接バインドはさせません。

ただ、させる人も結構いるようですし、この辺りは私にははっきりしたあるべき論は申し上げられません。

ということで、私の場合は
Modelのみで非同期処理は完結させています。
ViewModelからUIスレッドで受けた命令は、その先で非同期処理を行おうが行うまいがUIスレッドで完了通知を投げます。
ご参考までに。(全然参考にならない気もしますが。)

投稿2015/08/27 08:07

Tak1wa

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2015/08/27 08:14

回答ありがとうございます。 確かにViewModelは今のところModelとの調停程度ですのでTak1wa様の方法でも十分まとまりますね。 どちらの方法が良いのかまだ良くわからないので一度Model完結の方もテストしてみます。 貴重な意見、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問