我们有一个应用程序,其中有多个子系统在不同的线程中运行(即一个线程监视GPS,另一个监视RFID读取器等)。线程由服务注册表启动和监视,该注册表与win表单部分分开。
App的初始版本只有一个表单可以在更新计时器上运行,只需每隔一秒左右检查每个子系统上的静态变量值。
我正在尝试清理它,因为我们正在添加额外的表单,并且当前的方法几乎没有线程安全性。我希望每个子系统在其基础状态发生变化时抛出一个新事件,因此每个表单只能订阅它关心的事件,我们可以转移到响应更快的UI ...我不喜欢更新计时器方法。
我遇到了问题,因为在子系统线程中触发了事件,所以当我尝试使用事件传递的任何状态更新UI时,我得到System.InvalidOperationException异常抱怨跨线程调用。
所以目前,在阅读了msdn文档之后,我的选择是对我希望更新的每个字段使用control.invoke,这对于包含大量字段的复杂表单非常烦人,使用后台工作程序来运行子系统表单本身或表单仍然在计时器上运行并查询子系统本身,我正在努力避免。我希望表单尽可能与底层系统分开......他们应该只知道他们关心哪些事件并更新相关字段。
我的问题是,我在这里失踪了什么?有没有更好的方法来构建这个系统,以便子系统可以在自己的线程中运行,但仍然以非耦合方式发送通知?
任何帮助将不胜感激
欢呼声
nimai
答案 0 :(得分:1)
不要为要更新的每个字段调用,而是使用MethodInvoker BeginInvoke委托,并调用一次执行所有更新的方法。例如......
BeginInvoke( new MethodInvoker( MyUIUpdaterMethodHere ) );
答案 1 :(得分:0)
您可以查看Event Aggregator模式,它基本上允许松散耦合的pub / sub类型基于事件的体系结构。 Prism是Microsoft模式和实践团队的一个框架,用于使用WPF和Silverlight构建复合应用程序,它具有事件聚合,允许不同的UI组件以与您的设计目标类似的松散耦合方式相互通信。您可以查看它并尝试仅使用它的事件聚合部分。如果没有,您可以访问源代码,以便您可以制作符合您要求的内容。
答案 2 :(得分:0)
您可以使用Windows Forms Synchronization Context传入SendOrPostCallBackDelegate(或lambda),而后者又可以以线程安全的方式更新多个控件。
听起来这些子系统正在作为Windows服务运行。 您的winform应用程序如何与这些子系统进行通信。