C#发布/订阅服务-如何在后台线程上触发事件?

C#发布/订阅服务-如何在后台线程上触发事件?,c#,multithreading,C#,Multithreading,我开发了一些代码,从硬件设备接收一系列值,每50毫秒以名称/值对的形式接收一次。我想开发一个发布/订阅服务,在特定项目的价值发生变化时,可以通知订阅者。Subscribe方法可能如下所示:- public void Subscribe(string itemName, Action<string, long> callback) public void Subscribe(字符串itemName,操作回调) 读取硬件值的代码将检查自上次以来值是否已更改。如果是这样,它将遍历该项目

我开发了一些代码,从硬件设备接收一系列值,每50毫秒以名称/值对的形式接收一次。我想开发一个发布/订阅服务,在特定项目的价值发生变化时,可以通知订阅者。Subscribe方法可能如下所示:-

public void Subscribe(string itemName, Action<string, long> callback)
public void Subscribe(字符串itemName,操作回调)
读取硬件值的代码将检查自上次以来值是否已更改。如果是这样,它将遍历该项目的所有订阅者,调用他们的委托。目前,代理将在同一个线程上被调用,这并不理想——我需要尽可能快地保持轮询。在不同线程上调用回调委托的最佳方法是什么?订阅者应该传入(比如)一个任务/线程,还是发布者应该负责使这些任务/线程旋转起来

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


此外,我假设每次调用委托时创建一个新任务/线程会影响性能,因此可能需要某种“池”?

我将保持与您现在相同的结构,并将及时操作的责任放在回调上,即回调不应阻塞或执行复杂的操作,长时间的直接行动

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

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

编辑:


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

我将保持与您现在相同的结构,并将及时操作的责任放在回调上,即,回调不应直接阻止或执行复杂、冗长的操作

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

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

编辑:


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

小提示:当从不同线程读取窗体上的控件时,需要确保调用它们。最好的方法是
if([CONTROL].invokererequired)
然后
[CONTROL].Invoke(newmethodinvoker(()=>[GET或SET TO THE CONTROL])小提示:当从不同线程读取表单上的控件时,需要确保调用它们。最好的方法是
if([CONTROL].invokererequired)
然后
[CONTROL].Invoke(newmethodinvoker(()=>[GET或SET TO THE CONTROL])