0

コマンドを送信して応答を受信できるデバイスとの通信をセットアップしようとしています。ただし、無期限の待機時間を防ぐために、タイムアウト フラグを確実に制御したいと考えています。

私はこのようなことをしました:

private volatile EventWaitHandle _signal;

public void Send()
{
    // Do something

    _signal.WaitOne(30000);

    // Continue with something else

    _signal.Reset();
}

public void Receive() 
{
    _signal.Set();
}

私の質問は、Send メソッドと次のシナリオにアクセスできる複数のスレッド (この例では 2 つとしましょう) があるかどうかです。

スレッド A:

// Sends a "listen" command, but no response is received 
Send();

スレッド B:

// Sends a "cancel" command and response (success) is received
Send();

一貫性のない結果が得られます。つまり、理解できる 2 番目のコマンド (キャンセル) の応答を受け取ったときに両方のスレッドが続行することがありますが、最初のスレッドが 30000 ミリ秒のタイムアウトに達することがあります。これは説明できません。

私が見逃していることや間違っていることについて何かアドバイスはありますか?

4

1 に答える 1

3

EventWaitHandle は、ここでは適切な同期オブジェクトではありません。1 つのスレッドのみがコマンドを送信し、応答を待機している状態になることができるように、相互排除が必要です。言い換えれば、スレッドは厳密にデバイスと通信する順番を取らなければなりません。

ManualResetEvent はその保証を提供しません。Set() を呼び出すとすぐに、WaitOne() 呼び出しでブロックされているすべてのスレッドのブロックが解除されます。それが複数ある場合、2 つ以上のスレッドが同時にコマンドを送信しようとすると、プログラムが誤動作します。

Mutex は MUTual EXclusion を提供します。それがその名前の由来です。

于 2014-04-22T08:22:56.120 に答える