1

我开发了一些代码,它每 50 毫秒以名称/值对的形式从硬件设备接收一系列值。我想开发一个发布/订阅服务,当特定项目的值发生变化时,可以通知订阅者。订阅方法可能看起来像这样:-

public void Subscribe(string itemName, Action<string, long> callback)

读取硬件值的代码将检查自上次以来值是否已更改。如果是这样,它将遍历该项目的所有订阅者,调用他们的代表。就目前而言,代表将在同一个线程上被调用,这并不理想——我需要尽可能快地保持轮询。在单独的线程上调用回调委托的最佳方法是什么?订阅者应该传入(比如说)一个任务/线程,还是应该由发布者负责启动它们?

请注意,我需要将几个参数传递给委托(项目名称及其值),因此这可能会影响所采用的方法。我知道您可以将单个“状态”对象传递给任务,但要求订阅者实现一个 Action 回调委托(然后必须将其转换为包含名称和值的其他类型)感觉有点不直观。

另外,我假设每次调用委托时创建一个新任务/线程会损害性能,所以可能需要某种“池”?

4

1 回答 1

1

我会保持你现在拥有的相同结构,并将迅速采取行动的责任放在回调上,即。回调不应直接阻止或执行复杂、冗长的操作。

如果特定回调需要执行任何冗长的操作,它应该将操作数据排队到它自己的线程中,然后“立即”返回,例如。它可能 BeginInvoke/PostMessage 将数据发送到 GUI 线程,将其排队到插入 DB 表的线程或将其排队到记录器,(或者实际上,任何链接在一起的组合)。然后,这些冗长/阻塞操作可以在设备接口继续轮询的同时并行进行。

这样,您可以保留现有的工作结构,而不必对不需要它的回调施加任何线程间通信。设备接口保持封装状态,只是触发回调。

编辑:

“每次调用委托时创建一个新任务/线程会损害性能” - 是的,而且维护状态也很困难。通常,此类线程被编写为 while(true) 循环,顶部带有一些信号调用,例如。一个阻塞队列 pop(),因此只需要在启动时创建一次,并且永远不需要终止。

于 2012-08-16T09:55:54.447 回答