2

我的问题是关于确保我采用正确的方法并正确处理线程的反馈。我有一种感觉,我可能需要设置一些我自己的线程,所以欢迎所有反馈。

我遇到的问题是从零个或多个 RFID 阅读器读取 RFID 标签。我可以毫无问题地为单个读者阅读,因此从多个阅读者阅读不会成为问题。阅读器读取的每个标签或一批标签都由一个 .Net 事件传递。

我的计划是设置一个 ReaderControl 类,它维护阅读器、连接、启动、停止等。这个类将监听来自阅读器的TagRead事件。在它处理的每个事件上(大约每 250 毫秒),它会将读取的标签 ID(一个字符串)放入 HashSet 以保持它们的唯一性,HashSet 位于 ReaderControl 中。ReaderControl 将包含一个计时器,每 500 毫秒触发/消逝一次,此 TimerElapsed 事件由 ReaderControl 处理,它将打包迄今为止从所有阅读器读取的标签并引发TagsRead事件。这样做的目的是将事件触发保持在最低限度并减少重复标签。

TagsReads事件由另一个名为 TagTranslator 的类处理此类将遍历标签 ID(字符串)并计算出标签所指的内容,即 IPerson 对象。此类将在使用PeopleSeen事件完成翻译时触发一个事件。

PeopleSeen事件由 GUI(MVP 模式)中的模型处理总体思路是一个 GUI 显示,显示通过 RFID 阅读器的人的姓名。显示很简单,但很明显,标签正在被异步读取并被转换为要显示的“真实”对象。

你觉得 ReaderControl 应该在它自己的线程上运行吗,我认为它应该。无论GUI在做什么,我如何将这个类打包在它自己的线程中以继续阅读标签。还有,你认为当TagTranslator 处理事件的时候应该创建线程来处理翻译。

4

1 回答 1

4

我建议您使用并发队列数据结构和多生产者单消费者模型,而不是使用事件。将标签阅读器线程视为生产者,将处理线程视为消费者。

当一个线程从阅读器接收到一个标签时,它会将该标签添加到队列中,而不用担心重复或任何事情。哎呀,您可能在某个时候想要重复的信息。没有理由把它扔在这里。

消费者在队列中等待,取出物品并一次处理一件。

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 回答