计时器(多次调用 Elapsed 函数)

Timer (Calling Elapsed function several times)

我正在使用 System.Timers.Timer,其功能设置为 Elapsed。 'aTimer.Elapsed+=OnTimedEvent` 设置为定期触发。 假设这种情况每 5 秒发生一次。

如果由于某种原因 OnTimedEvent 的处理持续 超过 5 秒,会发生什么情况。

根据文档,* 该事件可能会在另一个 ThreadPool 线程上再次引发。在这种情况下,事件处理程序应该是可重入的。*

虽然我从理论上理解了这一点,但有人可以用更简单和实用的术语向我解释一下吗?


如果它对我的 onTimedEvent 有帮助,我正在尝试从 NetworkStream 中读取。

简单来说就是:OnTimedEvent应该能够支持多个线程同时通过它。为什么?因为当你的方法正在执行时,如果你不停止计时器,它会在 5 秒后再次触发。但是这次它将在另一个线程上触发,因为第一个线程正忙于执行第一个调用。因此,第二个线程将进入该方法。此时,如果 OnTimedEvent 不是线程安全的,就会发生不好的事情。

您可以 google 更多关于支持多线程的信息,您应该能够找到大量信息。

大多数时候,人们会在方法执行时停止计时器,然后在方法结束时重新启动它。但这取决于你的要求和你在做什么。

下面是一个非重入方法的例子:

static int sum = 0;

int increment(int i) {
    sum += i;
    return sum;
}

它是不可重入的,因为如果T1在执行它的方法内部并且将sum加1,sum将变为1。如果它被中断,意味着此时执行控制权交给T2,当T2 sum 的值不会是 0,而是 1。T2 会在 sum 和 return 上加 1。当 T1 回来时,它将从它停止的地方继续,即它已经完成了加法,所以它只会 return 1. 因此 2 个线程留下了不同的结果:T1 为 1,T2 为 2。因此,该方法不可重入。

要使其可重入,我们只需这样做:

int increment(int sum, int i) 
{
    return sum + i;
}

现在每个线程都将 return 得到相同的答案,即使它们在方法执行过程中离开也是如此,因为所有变量都在堆栈上并且不被线程共享(每个线程都有自己的副本的变量)。

This 如果您想阅读更多内容,那么答案中有很好的信息和解释。