VB.NET,.NET 4
大家好,
我有一个控制工业系统的应用程序。它有一个GUI,一旦进程启动,它主要显示各种附加设备的状态。它基本上是这样工作的:
我的问题是:程序偶尔会结冰。我在追踪这个问题上的无知努力使我怀疑,大多数时候,读写到由RS-232控制的设备的子集是罪魁祸首。然而,在程序冻结时,我偶尔会看到其他奇怪的东西,例如,它的文本属性由秒表的Elapsive毫秒属性决定的时间标签之一有时会显示一个不可能的值(例如-50小时或其他什么)。
对于RS-232问题,我怀疑读取事件与写事件同时执行,这会导致冻结(?)。我试图防止这种情况,方法是确保与RS-232设备的所有通信都通过具有以下属性的that ()子程序进行:
据我所知,这应该迫使一个传输()执行在另一个可以开始之前完全完成。如果一个传输()始终没有完成,那么另一个风险是代码在这里被阻塞了吗?
关于秒表故障,我推测问题在于,在执行秒表的Restart()方法的同时,计时器试图更新GUI标签。我不确定这会不会引起麻烦。我所知道的是,这个问题只发生在进程的某个时刻,此时将进行Restart()调用。
我想知道在标签被更新时,我是否可以使用SyncLock或者什么东西来锁定秒表(或者,反过来,当它被重新启动时)?或者,也许我应该停止计时器,重新启动秒表,然后再启动计时器,如:
Timer.Stop
Stopwatch.Restart
Timer.Start我对如何进行感到不安,这是因为我对.NET同步对象的实际工作方式完全缺乏了解。我已经尝试过在不同的地方使用一些SyncLocks,但是我真的不知道它们是否被正确实现。我想知道,在提供了所有这些上下文之后,某个非常聪明的人是否能够告诉我我是多么的愚蠢,以及如何正确地做到这一点。我真的很感谢你的任何意见。如果提供一些代码片段是有用的,我会很乐意这样做的,我只是担心每件事都是如此复杂,以至于它只会偏离我所希望的一个概念性问题。
提前感谢!布赖恩
发布于 2011-01-12 22:04:14
如果您在SCADA上工作,我会考虑转向任务调度框架,而不是依赖手动操作计时器。一个简单的起点将是类似于hardcodet.Scheduling类的东西,您可以转移到类似于石英这样的东西。大多数这类框架将为您提供暂停和恢复预定操作的方法。
如果我使用Modbus,通常会保留寄存器值的本地缓存,并对任何值进行更改,触发更改事件。这样做的好处是,在评估轮询响应时,您可以手动实现诸如刷新值之类的内容,而不会干扰进程调度和检查死区。这恰好是将轮询协议实现到OPC接口子集的副作用。
https://stackoverflow.com/questions/4674180
复制相似问题