一部のUSBシリアルポートアダプタが.NETでうまく動作しない理由を診断しようとしています。影響を受けるアダプターの動作は、SerialPort.Write()
の後です。 のいずれかを呼び出すと、SerialPort.Readxxx()
メソッドが約ReadTimout
までブロックされます。 私が発見した回避策は、ループをブロックしてBytesToRead
が <= 0
である間にブロックし、すべて正常に動作することです。どうして?.NETでのSerialPortクラスの問題
Sysinternals 'Portmonを使用してsome debug logsを収集しました。なぜこうなった?
without.log = bad behavior/bad USB adapter
with.log = with the while loop/bad USB adapter
ftdi.log = good behavior/good USB adapter
私はReadByte()の2つのネイティブ実装を書いており、問題の特性をより明確にすることができます。 ReadIntervalTimeoutとReadTotalTimeoutMultiplierをMAXDWORD ReadFile()に設定すると、 は、受信バッファにバイトが入るのを待ってから、MSDNの COMMTIMEOUTS構造体ページに記載されているように返されます。
これは、ReadByte()がシリアルポートを設定する方法であることを示しています。しかし、 ReadFile()がReadFile()と呼ばれるときに受信バッファが空の場合、ReadTotalTimeoutConstantまで待機してから復帰します。 MicrosoftのReadByte()もCommイベントを設定します。 Portmonログはイベントが発生していることを明確に示していますが、ReadByte()は受信バッファを読み取ることはありません。私はReadByte()のネイティブバージョンでこれを実装し、影響を受けるUSB-シリアルアダプタで完全に動作します。
DataReceivedEventは火に保証されていない、およびイベントの私のテストでは40%がアプリに到達することはありません –
"DataReceivedEventが発射することが保証されていない"理由を説明できますか? –
DataReceivedイベントは、受信されたバイトごとに発生するとは限りません。 BytesToReadプロパティを使用して、バッファに読み込まれるデータの量を判断します。http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx –