web-dev-qa-db-ja.com

ネットワーク産業機器への同期アクセス

ソフトウェアで制御する産業機器を持っています。ソフトウェアはソケットを使用してそれに接続し、時々機器にコマンドを送信している間、接続を常に維持します。現在、この機器は、データの送受信をカプセル化するクラスによって表されます。

次に、制御ソフトウェアから独立して、機器の状態を表示するUIを作成する必要があります(制御は同じソリューションの別のスレッドで行われます)。 UIの更新は毎秒行う必要がありますが、UIがデータの読み取りを必要とし、制御ソフトウェアが書き込みを必要とする場合があります。

問題は、機器が50ミリ秒から1秒まで応答する可能性があることです。これはわかりません。応答中は、誰も干渉してはなりません。

機器通信クラスへの通話を最適に同期するにはどうすればよいですか?

少なくとも2つの解決策があるかもしれません:

  1. 共通のメソッドごとに、C#で単純なlock(obj) {}ステートメントを使用します。クラス
  2. サブスクライバーの概念でイベントとメッセージキューを使用する

最初のものは単純かもしれませんが、すべてをブロックする可能性があるため、私の場合は最悪の解決策だと思います。

2つ目はもっと問題ないように見えますが、問題は、多くのサブスクライバーがいる場合、またはわからない場合、結果の受信に確かにある程度の遅延が発生することです。

PDATE:単純なロックを使用して実装しました。その理由は、一部の機器には、コントローラー側に複数の要求を処理する可能性がなく(一部にはありますが、ほとんどありません)、バッファーがオーバーフローするためです。したがって、何も悪いことが起こらないようにするために、排他的なREAD/WRITEロックは、これまでに見つけた最善の解決策であり、機能します。

1
XMight

どちらのソリューションでも機能します。このような値に書き込むときは、一般的にロックを適用することをお勧めします。大量の読み取りが予想される場合は、 ReaderWriterLockSlim を使用して書き込みロックを設定すると、他のスレッドが値を書き込むことができなくなりますが、ロックなしで読み取ることができます。これは、重要な領域の任意の時点で、値が機器の状態を正確に示していることを前提としています(つまり、別のスレッドがその瞬間に読み取る可能性があるため、一時的にゼロに設定しないでください)。

2番目のソリューションは、変更される値を、あるスコープで使用したいスレッドから切り離すため、個人的には2番目のソリューションを好みます。 ReaderWriterLockSlimを組み合わせて使用​​しますが、値変更イベントの公開を重要な領域に入れる必要はありません。この場合、単にUIを更新するだけの場合でも、サブスクライバーがイベントをどのように処理するかについて想定してください。プログラムが将来変更された場合、値に加えられた変更の新しい用途に対応するために、後でプログラムを簡単に適応させることができます。

お役に立てば幸いです。

2
Neil