0

今日、私はいくつかの奇妙な行動に出くわしました。SerialPortクラスを使用してアクセスするシリアルデバイスがあります。メイン アプリケーションには、ステータス更新のためにデバイスを 1 秒ごとにポーリングするタイマーがあります。ある時点で、時間のかかる作業を行う必要があるため、使用した GUI をブロックしないようにする必要がありますBackgroundworker。バックグラウンド ワーカーは、同じシリアル デバイスにアクセスするために 1 回必要です。時々アクセスがうまくいかないことがあります。古典的なmutli-threadシナリオ。そこで、新しいコマンドをシリアル デバイスに送信する関数で Mutex を使用してみました。

シリアル デバイスについては、すべてを独自のクラスにまとめました。このクラスにはsendCommand()、コマンドをデバイスに書き込み、AutoResetEventイベントを使用OnDataReceivedして応答を待つ関数があります。関数 sendCommand は、応答が受信されるかタイムアウトが発生するまでブロックします。Mutex次に、 sendCommand に入るときにを追加し、releaseMutex可能なすべての出口に を追加しました。それでも機能しません。

これを処理するより良い方法はありますか?

ありがとう、トバイアス

4

2 に答える 2

1

これとまったく同じことを行うアプリケーションがあります。シリアルアクセスクラスを作成し、(GUI またはバックグラウンドスレッドのいずれかから) それを呼び出すたびに、次のようにします。

private void myFunction(SerialClass myserialobject) {
  if (myserialobject == null)
    return;
  lock (myserialobject) {
    // code accessing the serial object
    // ...
    // when finished, close the lock statement
  }
}

メインスレッドとアクセスを必要とする他のスレッドの両方でこれを使用しました。ブロッキングですが、ブロッキングステートメントだと思います。

また、イベントにイベント ハンドラーを使用する代わりにOnDataReceived、シリアル オブジェクトが書き込み後にブロック読み取りを実行するようにしました。これにより、データが間違ったコンテキストで受信されるのを防ぐことができました。あなたのプログラムがどのように設定されているか正確にはわかりませんが、それを検討することをお勧めします。ポートへの書き込み時に読み取ると予想されるバイト数がわかっている場合に最適に機能します。そうすれば、Sleepすべてのデータが読み取られたことを確認するために使用する必要がなくなります。

于 2013-07-05T15:04:04.420 に答える