System.Timers.Timer()由于聚合了经过的事件而多次触发
本文关键字:事件 经过 Timer Timers 于聚 System | 更新日期: 2023-09-27 18:05:06
我想让我的一段代码在被调用时启动一个计时器,并且我想让这个计时器一直运行直到我退出整个程序。我的问题是,每次我调用OnSomethingHappens(),经过的事件聚集(尽管我的努力-=)和计时器开始触发一个额外的时间(或至少这是我认为正在发生的)。我还尝试在类中定义定时器,但无济于事。下面是我代码的相关部分:
public override void OnSomethingHappens()
{
Timer aTimer= new System.Timers.Timer();
aTimer.Elapsed -= (sender, e) => DoSomethingElse(sender, e);
aTimer.Stop();
aTimer.Close();
aTimer.Elapsed += (sender, e) => DoSomethingElse(sender, e);
aTimer.Interval = 1000;
aTimer.AutoReset = true; // I want the timer to keep working, but only fire once each time
Console.WriteLine("Enabling Timer aTimer");
aTimer.Start();
}
我不能使用静态(不确定这有什么帮助,但我看到计时器被定义为静态在许多源),因为这个类有许多实例,我希望他们有单独的计时器。
谢谢。
在没有AutoReset的情况下启动计时器,并在DoSomethingElse结束时重新启动。
aTimer.AutoReset = false;
aTimer.Start();
DoSomethingElse(..)
{
// do stuff here
aTimer.Start();
}
如果该类的每个实例都使用自己的计时器,则不需要静态。
private Timer _aTimer;
public void OnSomethingHappens()
{
if (_aTimer != null)
{
_aTimer.Enabled = true; // start timer
return;
}
_aTimer = new System.Timers.Timer();
_aTimer.Elapsed += DoSomethingElse;
_aTimer.Interval = 1000; // every 1 second
_aTimer.Enabled = true; // start timer
}
private void DoSomethingElse(object sender, ElapsedEventArgs e)
{
_aTimer.Enabled = false; // stop timer
// do w/e you want
}
首先应该只创建一个计时器实例,并连接一个事件侦听器。在当前代码中,每次调用该方法时都会创建一个带有事件侦听器的新计时器。相反,将计时器作为一个类变量,并在构造函数中连接事件侦听器。
你可以在OnSomethingHappens中启动定时器,但是你想在对该方法的后续调用中发生什么?计时器应该重新启动,还是继续?
您可能还希望将类设置为IDisposable,或者至少提供一个Stop方法,以便在应用程序关闭时停止计时器。
public class MyClass : MyBaseClass, IDisposable
{
private Timer _timer;
private volatile bool _isStopped = true;
public MyClass()
{
_timer = new Timer();
_timer.Interval = 1000;
_timer.Elapsed = OnTimerElapsed;
}
public void Stop()
{
_isStopped = true;
_timer.Stop();
}
public void Dispose()
{
if (_timer != null)
{
Stop();
_timer = null;
}
}
protected override void OnSomethingHappens()
{
if (_timer.Enabled)
{
// Restart or do nothing if timer is already running?
}
else
{
_isStopped = false;
_timer.Start();
}
}
private void OnTimerElapsed(object sender, EventArgs a)
{
if (_isStopped)
{
// If the Stop method was called after the Elapsed event was raised, don't start a long running operation
return;
}
}
}