2011-01-12 12 views
0

VB.NET、.NET 4VB.NET同期混乱

こんにちはすべて、

私は産業システムを制御するアプリケーションを持っています。 GUIには、いったんプロセスが開始されると、主にさまざまな接続デバイスの状態が表示されます。これは基本的に次のように機能します。

  • System.Timers.Timerオブジェクトは常に実行されています。各Elapsedイベントで、デバイスは現在の値をポーリングし、GUIのコントロールを呼び出して新しい値で更新します。
  • 開始ボタンをクリックすると、プロセスタイムストップウォッチオブジェクトが作成され、開始されます(GUI上のラベルは、System.Timers.TimerのElapsedイベントで呼び出され、更新されます)。プロセス実行し、新しいスレッドが作成され、このイベント)
  • 方法(
  • いくつかのストップウォッチのオブジェクトが作成され、開始され)サブルーチンが(これらのストップウォッチは、定期的に再起動します(を経由して処理中に再起動されます)。
  • は、いくつかのロジックがあります新しいStopwatchsのElapsedmillisecondsプロパティで実行され、デバイスに新しい設定値を書き込む、データログを更新するなどの作業をいつ行うかを決定します。

私の問題は次のとおりです。プログラムが時折フリーズします。問題を突き止めるための私の無知な努力は、RS-232で制御されているデバイスのサブセットへの読み書きが、ほとんどの場合の犯人であると疑うようになった。ただし、プログラムのフリーズ時に他の奇妙なものが見られることがあります。たとえば、ストップウォッチのElapsedmillisecondsプロパティでTextプロパティが決定されたラベルの1つが不可能な値(-50時間など)を示すことがあります。

RS-232の問題については、書き込みイベントと同時に読み取りイベントが実行されていると思われ、フリーズ(?)が発生します。

どの、限り自分の無知が私を許可するように理解するために:私は、RS-232デバイスとのすべての通信には、次の属性を持つ送信()サブルーチンによって注ぎ込まれていることを確認することでこれを回避しようとしましたあるTransmit()の実行が完全に終了してから別のTransmit()を開始できるようにする必要があります。 1つのTransmit()が終了しないと、ここでコードがブロックされる可能性があります。

ストップウォッチの問題については、ストップウォッチのRestart()メソッドが実行されているときに、タイマーがGUIラベルを更新しようとしているという問題があると推測します。これが問題を引き起こすかどうかはわかりません。私が知っていることは、この問題は、Restart()呼び出しが行われるときのプロセスのある時点でのみ発生していることです。

ラベルが更新されている間(逆に、再起動中)にSyncLockなどを使用してストップウォッチをロックすることができますか?または、おそらく私は、タイマーを停止するストップウォッチを再起動し、続行する方法についてはそう?:

Timer.Stop 
Stopwatch.Restart 
Timer.Start 

私の不安はどのように.NET同期の理解の私の完全な欠如に起因しているように、再びタイマーを開始する必要がありますオブジェクトは実際に動作します。私は様々な場所でいくつかのSyncLockを叩いてみましたが、正しく実装されているかどうかはわかりません。私は、この文脈をすべて提供して、本当に賢い人が私がどうやって愚かで、これをどうやって行うのか教えてくれるのだろうかと思っています。私は本当にすべての入力を感謝します。いくつかのコードスニペットを提供すると便利なのであれば、私はうれしいことですが、すべてが畳み込まれていることを心配しています。

ありがとうございます! ブライアン

+1

私はこれらのような質問は嫌いです。答えは決して高く評価されないため、コメントのみです。あなたは非常に深刻な問題を抱えています。おそらく、あなたが思うよりも悪いです。あなたはスレッドを走らせています。最後のElapsedイベントがまだ完了していなくても、System.Timers.Timerは別のスレッドを開始するだけなので、それらを実行するには絶対的な最悪の方法を使用しています。これはスレッディングの難しさの教訓の1つです。バージョン2.0について考え始めてください –

+0

RS232についてのメモ...同時に送受信できます。また、はい、いくつかのRS232 USBハードウェアはかなりフレークであり、あらゆる種類のトラブルを引き起こす可能性があります。スレッドの問題は根本的な問題である可能性が高いので、Hansのアドバイスを取るべきです。 – Brad

+0

申し訳ありませんハンス。私の質問はあいまいだと思います。私はプログラミングに非常に素人で、自分の道を見つけようとしています。私は、スケジューラに頼るためのGregの提案を実装するバージョン2の作業に取り掛かると思います。それは有能なプログラマーのコードにもっと頼り、自分のゴミを少なくするという追加の利点があります。私は疑問に思っていますが、「スレッディングは根本的な問題である可能性があります」というようなステートメントにつながると確信していますか?私はスレッディングに関するリスクを把握するのに十分理解していません。 –

答えて

1

SCADAに関係するものがあれば、タイマーの手動操作に頼るのではなく、タスクスケジューリングフレームワークへの移行を検討します。簡単な出発点は、hardcodet.Schedulingクラスに似ていて、Quartzという獣のようなものに移動することができます。これらのタイプのフレームワークのほとんどは、スケジュールされたアクションを一時停止および再開する方法を提供します。

私がModbusで作業している場合は、通常、レジスタ値のローカルキャッシュを保持し、変更イベントを発生させる値を変更します。これは、プロセススケジューリングを妨げずに手動で値をリフレッシュしたり、ポーリングされたレスポンスを評価する際にデッドバンドをチェックしたりするなどの機能を実装できるという利点があります。これは、OPC DAインターフェースのサブセットにポーリングされたプロトコルを実装することの副作用となりました。

+0

私の不明確な質問に対する答えは正確ではありませんが、私はQuartzを読んでテストしています。私はこの数ヶ月前に私が知っていたことを本当に望む!それを指摘してくれてありがとう。 –