我正在写一个Windows服务来每隔x分钟执行一些方法,但我希望该方法相对于计时器本身同步执行。 Windows服务有一个Timer对象(System.Timers.Timer),它每隔x分钟启动并调用一些方法'DoWork',但定时器必须在'DoWork'执行时'停止'并在方法完成后再次启动。
我知道使用System.Windows.Forms.Timer类会给我我想要的行为,但我不想将System.Windows.Forms dll引用添加到我的服务项目中。
以下是“正常工作”代码的示例:
private System.Timers.Timer timer1;
public void MainMethod()
{
timer1 = new System.Timers.Timer();
timer1.Interval = 1000;
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
timer1.Start();
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
timer1.Stop();
DoWork();
timer1.Start();
}
private void DoWork()
{
Thread.Sleep(2000);
Console.WriteLine("found!");
}
在控制台应用程序中运行(在编写Windows服务之前作为模型),预期的行为应该是控制台写入'found!'每3秒钟一次。
只是旁注:我只是使用'Thread.Sleep(2000)来模仿延迟,但它不会构成实际代码库的一部分。
除此之外,还有其他/“更好”的方法来实现这一目标吗?
感谢您阅读我的问题,我们将非常感谢任何意见。
答案 0 :(得分:3)
你不能在Windows服务中使用System.Forms.Timer
因为这需要一个消息泵而且Windows服务没有给出一个非常大的消息泵栈(另外你必须调用{{1}开始一个)。
现在你拥有它的方式是我实现定期事件的方式。我会添加一些东西来监控你的活动是否需要比这段时间更长的时间;但除此之外......
答案 1 :(得分:0)
我认为这取决于你是否只想在方法调用之间的第二个延迟是一个常量,或者你是否希望每X秒调用一次方法,但是如果方法需要的时间长于执行X秒。
上面的代码将执行前者,其中方法调用之间有一秒钟的延迟,但如果您希望每隔X秒调用一次方法,则可能需要考虑使用DateTime.Now
和{{{时间戳1}}查看自上次方法调用以来是否已经过了合适的时间。如果系统时钟发生变化,这可能会导致异常行为,例如在夏令时,方法可能无法运行一小时,但在您的情况下,这种异常行为可能被您认为是可接受的。
答案 2 :(得分:-1)
似乎你遇到的主要问题被描述为“当'DoWork'正在执行时定时器必须'停止'并在方法完成后再次启动”。简而言之,该服务需要是多线程的。您应该考虑使用线程池。使用线程池将允许执行线程继续计算后台线程执行其他工作的时间。在这里查看ThreadPool文档:http://msdn.microsoft.com/en-us/library/3dasc8as%28v=vs.80%29.aspx。