我希望我的代码的一部分在调用后启动一个计时器,我希望这个计时器继续运行直到我退出整个程序。我的问题是,每当我调用OnSomethingHappens()时,Elapsed事件聚合(尽管我努力使用 - =)并且计时器开始激发一个额外的时间(或者至少这是我认为正在发生的事情)。我也试过在课堂上定义计时器,但没有用。这是我的代码的相关部分:
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();
}
我不能使用静态(不确定这会有什么帮助,但我看到定时器在许多来源中被定义为静态)因为这个类有很多实例,我希望它们有不同的定时器。
谢谢。
答案 0 :(得分:6)
在没有AutoReset的情况下启动计时器,并在DoSomethingElse结束时重新启动计时器。
aTimer.AutoReset = false;
aTimer.Start();
DoSomethingElse(..)
{
// do stuff here
aTimer.Start();
}
答案 1 :(得分:3)
如果此类的每个实例都使用自己的计时器,则不需要静态。
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
}
答案 2 :(得分:2)
首先,你应该只创建一次计时器实例,并挂钩一个事件监听器。使用当前代码,每次调用方法时,都会创建一个带有事件侦听器的新计时器。而是使计时器成为类变量,并在构造函数中挂钩事件侦听器。
你可以在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;
}
}
}