16

CF2.0 で C# のシリアル ポートと通信するために書いたコードを確認しているところです。信頼できないため、DataReceived イベントは使用していません。MSDN は次のように述べています。

DataReceived イベントは、受信したバイトごとに発生する保証はありません。BytesToRead プロパティを使用して、バッファ内で読み取るデータがどれだけ残っているかを判断します。

ポートを read() でポーリングし、読み取られたデータを処理するデリゲートを用意しています。「ポーリングが悪い」ということもどこかで読みました(説明はありません)。

ポーリングが悪い理由はありますか? 通常のスレッドに関する注意事項とは別に、ポートをポーリングする別のスレッド (バックグラウンド スレッド) があり、データが読み取られた後にスレッドが終了し、すべてテストされ、正常に動作します。

4

3 に答える 3

19

私が読んだ方法では、バイトごとに 1 つのイベントではなく、複数のバイトに対して 1 つのイベントを取得する可能性があります。データの準備ができたときにイベントを取得することを期待し、一部のバイトを完全に「スキップ」することはありません。

私はいつもこのイベントを使用してきましたが、問題はありませんでした。

于 2009-03-13T21:06:27.080 に答える
9

「ポーリングはよくない」というのが一般通念です。これは、多くの場合、CPU バウンド プロセスになるためです。代わりにブロッキング I/O を使用すると、イベントが発生するまで CPU を他のプロセスで使用できます。

とは言うものの、通常、使用可能な文字がない場合にポーリングが戻る前に (短い) タイムアウトを待機するように設定することは可能です。適切なタイムアウトを選択すると、単純なポーリング ループで使用される CPU 時間が大幅に短縮され、他のプロセスも実行されます。

私は C# のシリアル ポートをまったく使用したことがありませんが、ドキュメンテーションが意味することを推測する危険があります。

DataReceived イベントは、受信したバイトごとに発生するとは限りません。BytesToRead プロパティを使用して、バッファ内で読み取るデータがどれだけ残っているかを判断します。

キャラクターごとに 1 つのイベントを取得することは期待できないということです。状況によっては、複数のキャラクターが利用可能なイベントを配信する場合があります。イベント ハンドラーで使用可能なすべての文字を取得するだけで、すべてがうまくいきます。

編集:リーダースレッドでブロッキング呼び出しを行うことが、全体として最良の答えかもしれません。文字が到着するまでスレッドがブロックされるため、それ自体はポーリングではありません。固定サイズのチャンクではなく、到着したデータを処理する必要がある場合は、バッファー サイズと一部のシリアル ポート設定を調整する必要がある場合があります。

于 2009-03-13T21:08:20.133 に答える
3

ブロッキング Read 呼び出しを使用している場合でも、基になるシリアル ポート ドライバー コードは割り込み駆動型であると確信しています。

于 2010-07-25T18:50:32.237 に答える