USB デバイスとやり取りするために C# で作成したユーティリティがあります。汎用の HID ドライバーを使用し、デバイスへのハンドルをFileStream
オブジェクトにラップします。BeginRead
メソッドとメソッドを使用してデータの読み取り/書き込みを行いBeginWrite
ます。これは、非同期 IO が必要だからではなく、デバイスが (意図的かどうかに関係なく) 通信不能状態になった場合にタイムアウトできるようにするためです。すべての読み取り/書き込みは、独自の専用 IO スレッドで行われます。
スレッドのデッドロックが疑われるケースをいくつか見たので、私は物事を適切に行っていないのではないかと心配しています。これは、関連するRead
メソッドの簡略化されたバージョンです (これはうまく機能しているようです)。
if (_readResult == null)
{
_readResult = _deviceStream.BeginRead(_readBuffer, 0, _readBuffer.Length, null, null);
}
if (_readResult.AsyncWaitHandle.WaitOne(IOTimeout, true))
{
int bytesRead = _deviceStream.EndRead(_readResult);
_readResult.AsyncWaitHandle.Close();
_readResult= null;
// … Copy bytes to another buffer
}
else
{
// … Timeout, so retry again in a bit
}
私の主な質問は、IO スレッドを終了する必要があり、デバイスが通信しなくなった場合に、未完了BeginRead
または呼び出しを適切に停止する方法です。そこに座って永遠にブロックするので、BeginWrite
私はただ電話することはできません。読み取り/書き込み操作が保留中EndRead
に呼び出しても安全ですか?Filestream.Close
また、保留中の読み取り操作と書き込み操作を同時に実行しても安全ですか? たとえば、読み取りメソッドがタイムアウトした場合でも、先に進んで何かを書き込もうとすることはできますか?
現在のデッドロックの問題を再現するのは難しいですが、本当に奇妙なのは、読み取りメソッドで IO スレッドが「スタック」したときに開始するように見えることです。私のコードが思った通りに動作しない限り、それがどのように起こるかはわかりません。