2011-02-04 93 views
2

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

我遇到的问题是从零个或多个RFID阅读器读取RFID标签。我可以阅读一个没有问题的阅读器,所以从几个阅读器不会是一个问题。阅读器读取的每个标签或一批标签由.Net事件提供。

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

TagsReads事件由另一个名为TagTranslator的类处理。这个类将遍历标记ID(字符串)并计算出标记引用的内容,即IPerson对象。该课程将在翻译完成后触发事件PeopleSeen事件。

PeopleSeen事件由GUI(MVP模式)中的模型处理。总体思路是GUI显示器显示通过RFID阅读器的人的姓名。显示器很简单,但显然在引擎盖下,标签正在被读取,并被翻译成“真实”的对象来显示。

你觉得ReaderControl应该在自己的线程上运行,我认为它应该。我如何在自己的线程中打包这个类,以便不管GUI正在做什么而继续阅读标签。另外,您是否认为TagTranslator在处理事件时应该创建线程来处理翻译。

+0

听起来像处理我听过的RFID的最复杂的CPU密集型方式 – 2011-02-04 17:56:57

+0

为什么这会成为CPU密集型? – JonWillis 2011-02-05 21:13:57

回答

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,并使干净和简单的代码执行得很好。