2

私の質問は、私が正しいアプローチを取っていることを確認し、スレッドを正しく処理することに関するフィードバックです。私は自分のスレッドのいくつかを設定する必要があるかもしれないと感じているので、すべてのフィードバックを歓迎します.

私が抱えている問題は、0 個以上の RFID リーダーから RFID タグを読み取ることです。私は問題なく単一のリーダーを読むことができるので、複数から読むことは問題になりません。リーダーによって読み取られた各タグまたはタグのバッチは、.Net イベントによって配信されます。

私の計画は、リーダー、接続、開始、停止などを維持する ReaderControl クラスをセットアップすることです。このクラスは、リーダーからのTagReadイベントをリッスンします。処理する各イベント (約 250 ミリ秒ごと) で、読み取ったタグ ID (文字列) を HashSet に入れてそれらを一意に保ちます。HashSet は ReaderControl にあります。ReaderControl には、500 ミリ秒ごとに起動/経過するタイマーが含まれます。この TimerElapsed イベントは、これまでにすべてのリーダーから読み取られたタグをパッケージ化し、TagsRead イベントを発生させる ReaderControl によって処理されます。これの目的は、イベントの発生を最小限に抑え、タグの重複を減らすことです。

TagsReadsイベントは、 TagTranslatorという別のクラスによって処理されます。このクラスは、タグ ID (文字列) をループして、タグが参照するもの、つまり IPerson オブジェクトを解決します。このクラスは、PeopleSeenイベントで翻訳が完了するとイベントを発生させます。

PeopleSeenイベントは、GUI のモデルによって処理されます(MVP パターン)。全体的なアイデアは、RFID リーダーを通過する人の名前を GUI 表示することです。表示は単純ですが、明らかにフードの下でタグが非同期で読み取られ、表示される「実際の」オブジェクトに変換されています。

ReaderControl は独自のスレッドで実行する必要があると思いますか?そうすべきだと思います。このクラスを独自のスレッドにパッケージ化して、GUI が何をしているかに関係なくタグを読み続けるにはどうすればよいですか。また、イベントを処理するときに TagTranslator が翻訳を処理するスレッドを作成する必要があると思いますか。

4

1 に答える 1

4

イベントを使用するのではなく、並行キューデータ構造と複数のプロデューサー、単一のコンシューマーモデルを使用することをお勧めします。タグリーダースレッドをプロデューサー、処理スレッドをコンシューマーと考えてください。

スレッドがリーダーからタグを受け取ると、重複などを気にすることなく、そのタグをキューに追加します。一体、ある時点でその重複した情報が必要になる場合があります。ここに捨てる理由はありません。

消費者はキューで待機し、アイテムを取り出して一度に1つずつ処理します。

クラスはこれBlockingCollectionに最適です。

// Shared queue.  Assuming that a tag is simply a string.
BlockingCollection<string> TagQueue = new BlockingCollection<string>();

// Tag reader threads (producers)
while (!ShutdownMessageReceived)
{
    string tag = GetTagFromReader(); // however that's done
    TagQueue.Add(tag);
}

// Processing thread (consumer)
while (!ShutdownMessageReceived)
{
    string tag = TagQueue.Take();
    // process the tag
}

BlockingCollection複数のプロデューサーとコンシューマーをサポートするため、それぞれを好きなだけ持つことができます。アイテムが利用可能になるまで、Takeメソッドはブロックします。ビジーウェイトではないため、ポーリングのオーバーヘッドはありません。

この種のことは、で実装するのが非常に簡単でBlockingCollection、非常にうまく機能するクリーンでシンプルなコードになります。

于 2011-02-04T18:59:59.017 に答える