1

出于某种奇怪的原因,Elapsed 事件触发了两次,它肯定应该触发一次。紧接着,计时器停止工作......代码结构有点像这样:当某个对象包含的某个值(以 500-1500 毫秒的间隔不断更新)增加超过 X 时,它被定义为触发某个事件与前一个值相比较的总和。

例如,如果我将 X 定义为 2,并且我收到的值是 1、2、1、2、3、4、8,那么当输入 8 时,该事件将触发。该事件的事件处理程序启动上述计时器,该计时器在它过去之前运行 Y 时间并触发有问题的事件。如果在计时器结束之前该值恢复正常,则重置计时器。

因此,总体结果应该是一个测量某个动态值的应用程序,并监视它是否存在超过 Y 秒时间发生的大 X 大小异常。

代码中的整体结果看起来像

vMonitor.Range=X;
vMonitor.Over+= new EventHandler(StartTimer);
vMonitor.Normal+= new EventHandler(StopTimer);
vTimer.Elapsed+= new EventHandler(RaiseAlert);
source.BeginUpdate(vMonitor.Value);

实际的问题是 RaiseAlert 在计时器经过时被触发两次,然后就好像计时器完全停止工作,不再触发。我认为值得一提的是,整个应用程序包含大量线程活动,一次至少运行 2 个线程,更新 vMonitor 值。

有什么想法吗?

更新:

关于线程问题,解释确切的结构相当复杂,但我可以说 vMonitor 对象包含在另一个对象中,该对象包含更新值,该值由各个线程不断更改,当然是受监视的. 每当父对象的值更新时,它与 vMonitor 进行比较,并触发适当的事件。vMonitor 中的值随后被父对象值替换。

编辑:我刚刚再次验证了它, vTimer.Elapsed 委托仅包含一个正确的事件处理程序。

4

3 回答 3

3

来自MSDN

Elapsed 事件在 ThreadPool 线程上引发。如果 Elapsed 事件的处理持续时间超过 Interval,则该事件可能会在另一个 ThreadPool 线程上再次引发。因此,事件处理程序应该是可重入的。

于 2008-10-28T01:50:39.883 回答
0

编辑以考虑米奇所说的话,因为我完全忘记了这是最简单的答案。在处理 Elapsed 事件的方法中,请确保您首先停止计时器,以便在处理事件时不会再次触发该事件。

于 2008-10-28T01:39:08.050 回答
0

好吧,我最基本的直觉是,您实际上有两个事件连接到 Elapsed 事件 - 导致两个事件触发。我已经被这个抓住了,有时是因为我已经在设计器中添加了事件连接时手动添加了它,或者这里有一些继承方面,连接已经在基类中并且你正在重复它在派生类中。

当然,如果有多个线程,那么这是一个完全不同的球赛!

于 2008-10-27T08:50:47.117 回答