在System.Timers.Timer之后,我创建了一个控制台应用程序来练习:
public class Program
{
//private static System.Timers.Timer aTimer;
public static void Main()
{
short_running_method();
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
}
static void short_running_method()
{
// Normally, the timer is declared at the class level,
// so that it stays in scope as long as it is needed.
// If the timer is declared in a long-running method,
// KeepAlive must be used to prevent the JIT compiler
// from allowing aggressive garbage collection to occur
// before the method ends. You can experiment with this
// by commenting out the class-level declaration and
// uncommenting the declaration below; then uncomment
// the GC.KeepAlive(aTimer) at the end of the method.
System.Timers.Timer aTimer;
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
// If the timer is declared in a long-running method, use
// KeepAlive to prevent garbage collection from occurring
// before the method ends.
//GC.KeepAlive(aTimer);
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
我理解(如果我错了,请纠正我)只要程序正在运行并且事件持续无限激活,在类级别声明的计时器对象就是活动的。通过注释掉类级别声明的计时器对象并在short_running_method中取消注释声明,我认为如果不使用GC.KeepAlive(aTimer)并且事件应该停止触发,则在一定时间后应该对atimer对象进行垃圾收集。然而,在我的实验中,事件似乎永远不会停止,即使在30分钟之后它仍然会被提升。有人可以澄清为什么会这样吗?
答案 0 :(得分:0)
问题在于从事件源到事件监听器的强引用:
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
所以,你可能会在这里寻找弱事件模式: Weak Event Patterns on MSDN
此外,要停止计时器,您可以使用:
aTimer.Stop();
您还可以通过将已启用设置为false来停止计时。
提升Elapsed事件的信号总是排队等待在ThreadPool线程上执行,因此事件处理方法可能在一个线程上运行,同时调用Stop方法在另一个线程上运行。 这可能会导致在调用Stop方法后引发Elapsed事件。下一节中的代码示例显示了解决此竞争条件的一种方法。