Вопрос о потоке C # с RFID - PullRequest
       21

Вопрос о потоке C # с RFID

2 голосов
/ 04 февраля 2011

У меня вопрос к обратной связи, чтобы убедиться, что я выбрал правильный подход и правильно обработал потоки. У меня есть ощущение, что мне может понадобиться установить некоторые из моих собственных тем, поэтому любые отзывы приветствуются.

У меня проблема с чтением меток RFID с нуля или более считывателей RFID. Я могу читать для одного читателя без проблем, поэтому чтение из нескольких не будет проблемой. Каждый тег или пакет тегов, прочитанный читателем, доставляется событием .Net.

Мой план состоит в том, чтобы настроить класс ReaderControl, который будет поддерживать считыватели, подключение, запуск, остановку и т. Д. Этот класс будет прослушивать события TagRead от читателей. Для каждого события, которое он обрабатывает (примерно каждые 250 мс), он помещает идентификаторы тегов чтения (строку) в HashSet, чтобы сохранить их уникальность, а HashSet находится в ReaderControl. ReaderControl будет содержать таймер, который запускается / истекает каждые 500 мсек, это событие TimerElapsed обрабатывается ReaderControl, который будет упаковывать теги, прочитанные на данный момент всеми читателями, и вызывать событие TagsRead . Цель этого состоит в том, чтобы свести событие к минимуму и уменьшить количество дублирующих тегов.

Событие TagsReads обрабатывается другим классом, называемым TagTranslator. Этот класс будет перебирать идентификаторы тега (строки) и определять, к чему относится тег, т. Е. Объект IPerson. Этот класс вызовет событие по завершении перевода с событием PeopleSeen .

Событие PeopleSeen обрабатывается моделью в графическом интерфейсе (шаблон MVP). Общая идея заключается в том, что дисплей с графическим интерфейсом показывает имена людей, которые проходят через считыватели RFID. Дисплей просто, но, очевидно, под капотами, теги читаются в асыче и переводятся в «реальные» объекты для отображения.

Считаете ли вы, что ReaderControl должен работать в своем собственном потоке, я думаю, что он должен. Как мне упаковать этот класс в его собственный поток, чтобы просто продолжать читать теги независимо от того, что делает GUI. Кроме того, вы думаете, когда TagTranslator при обработке событий должен создавать потоки для обработки перевода.

1 Ответ

4 голосов
/ 04 февраля 2011

Я бы предложил, чтобы вместо использования событий вы использовали параллельную структуру данных очереди и модель с несколькими потребителями для одного потребителя. Думайте о нитях читателя тегов как о производителях, а о нитях обработки как о потребителях.

Когда поток получает тег от читателя, он добавляет этот тег в очередь, не заботясь о дубликатах или чем-либо еще. Черт, вы можете хотеть , что дублирует информацию в какой-то момент. Нет причин выбрасывать это прямо здесь.

Потребитель ждет в очереди, снимая элементы и обрабатывая их по одному.

Класс 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, и они обеспечивают чистый и простой код, который очень хорошо работает.

...