2009-03-13 43 views
15

CF2.0のC#でシリアルポートと通信するために書いたコードを見直しています。 信頼できないため、私はDataReceivedイベントを使用していません。 MSDN states that:シリアルポート通信:シリアルポートを使用してシリアルポートをポーリングするDataReceivedイベント

DataReceivedイベントは、受け取ったすべてのバイト 用に飼育される gauranteedではありません。 BytesToReadプロパティ を使用して、 にバッファに読み込まれるデータの量を決定します。

私はread()でポートをポーリングし、読み取り時にデータを処理するデリゲートを持っています。私はまた、「ポーリングは悪い」(説明はありません)というどこかを読んでいます。

ポーリングが悪い理由は何ですか?私は別のスレッド(バックグラウンドスレッド)を持ってポートをポーリングし、スレッドはデータが読み込まれた後に終了し、すべてテストされ、うまく動作します。

答えて

17

私が読んだところでは、バイトごとに1つのイベントではなく、複数のバイトに対して1つのイベントが発生する可能性があります。私はまだデータが準備されているときにイベントを受け取ることを期待し、いくつかのバイトを完全に「スキップ」しないようにします。

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

+1

もちろん、これも私の経験です。 – Andy

7

従来の知恵では、「ポーリングは悪い」というのは、しばしばCPUに縛られるプロセスに終わってしまうからです。ブロックI/Oが代わりに使用されている場合、イベントが発生するまでCPUは​​他のプロセスで使用できます。

これは通常、ポーリングが(短い)タイムアウトを待ってから文字が利用できなくなったときに戻るように設定できることです。適切なタイムアウトを選択すると、単純なポーリングループでCPU時間が大幅に短縮され、他のプロセスも実行されます。

私はすべてのC#からシリアルポートを使用していないが、私はドキュメントが

によって何を意味するのかDataReceivedイベントが受信バイト毎提起されることが保証されていないことを推測するハザードつもりです。 BytesToReadプロパティを使用して、バッファに読み込まれるデータの量を判断します。

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

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

+0

感謝しますね。私はCPUをブロックしていません。私のアプリでは、ユーザーはデバイスから値を取得するか、手動で入力する必要があります。いずれかが発生した場合、ポーリングスレッドは終了します。 – sarsnake

1

Block Readコールを使用していても、基本的なシリアルポートドライバコードが割り込み駆動型であることは間違いありません。

関連する問題