複数機器を制御するアプリケーションのマルチスレッド設計について
いつもお世話になります。
主題の件について、長文になってしまいますが、ご意見・ご教授をお願い致します。
前提条件
システム要件
例として、以下の図のようなイメージ構成のシステムを考えます。
今回作成するアプリケーションはソフトウェアFOO
に該当します。
このシステムは、以下の動作を行います。
FOO
は、複数のマシンを制御するアプリケーションである- 各マシンは非同期的に動作を行う
FOO
は各マシンと通信にて制御を行うFOO
は基本的にはサーバ的な役割を行う(マシンから通知が来たら、何かしらの処理をして返す)- ただし、
FOO
から能動的に、各マシンへ動作を指示する場合もある
(例えば、停電発生時に各機器への縮退指示など) - 図にはないですが、
FOO
内の各コントローラは、例えば「電源状態」とか「システムスケジュール」といった共通のステータスを参照する - 図にはないですが、
マシンA
が動いているときは、マシンB
は停止するといった、マシン間の制御も行う必要がある
開発環境
- C#を使用した.NETアプリケーション
現状のソフトウェア設計
- 各コントローラは1つのコントローラクラスのインスタンスとして、Factoryクラスから生成する
悩んでいる点
ここで、「マシンAのコントローラ」等の、各コントローラでどのように処理を実現すべきか悩んでいます。
具体的に、各コントローラはそれぞれ非同期(ときには同期)で処理を行うことになるのですが、以下の2パターンを構想しています。
<構想1>
- コントローラクラスを常駐スレッド化する
→つまり、各コントローラそれぞれに常駐スレッドを設ける - インフラストラクチャー層とはスレッド間メッセージキュー等でやり取りして、各マシンの制御を行う
<構想2>
- コントローラクラスは常駐スレッドを持たない
- マシンからメッセージを受け取ると、インフラストラクチャー層からコールバックでコントローラへ通知を行い、それをきっかけとして非同期処理を開始し、処理が終わると非同期処理を終了する。
(イメージとしては、C#でいうと、Task.Run()
で非同期処理を行い、各コントローラごとの常駐スレッドはなしで処理を行う)
つまり、構想1・2において、「常駐スレッドをたてる」か「通知が来たときのみ非同期処理を行う」かの違いがあります。
それぞれ、以下の特徴があると考えています。
- 構想1は、コントローラインスタンスというオブジェクトが、メッセージを受け取ると能動的に処理を行うという点において、オブジェクト指向っぽいやり方である。
ただし、複数スレッドが常駐するため、全体としての制御が難しい? - 構想2は、必要な時に必要なタイミングでマルチスレッドで動作を行うので、スレッドの資源を有効的に使える。
そして、C#ではマルチスレッド処理はTask
を使用するのが一般的と聞いたので、C#で実現するならこちらのほうが推奨されている?
<補足>ソフトウェアに要求される性能
ソフトウェア的には、パフォーマンスはそこまで要求されません。
どちらかというとメンテナンス性(変更容易性や可読性など)が要求されます。
質問点
- 上記の構想1・2において、どちらを選択すべきでしょうか。(または他に選択すべき方法があるでしょうか)
→どちらがメンテナンス性に優れているでしょうか。 - どちらのやり方が一般的なのでしょうか。
個人的な考えとしては、C#の時流がTask
による非同期処理なので、構想2が妥当なのかなと思いますが、メンテナンス性や可読性は構想1の方が優れているのかなと感じています。
また、以下の点においてもご意見頂ければ助かります。
- そもそも、それぞれの構想の特徴の捉え方は間違っていないでしょうか。
- もし同じような経験をされた方がおられましたら、アドバイス頂けますでしょうか。
以上、長くなりましたが、よろしくお願い致します。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/09/02 06:16