1

我正在编写一个 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 服务之前的模型),预期的行为应该是控制台写“找到!” 每 3 秒。

只是一个旁注:我只是使用 'Thread.Sleep(2000)' 来模拟延迟,但它不会构成实际代码库的一部分。

是否有任何其他/“更好”的方式来实现这一点而不是我上面的方式?

感谢您阅读我的问题,任何输入将不胜感激。

4

3 回答 3

3

您不能System.Forms.Timer在 Windows 服务中使用,因为这需要消息泵,并且 Windows 服务没有提供可能非常大的消息泵堆栈(而且您必须调用Application.Run才能启动)。

你现在拥有它的方式就是我实现周期性事件的方式。我会添加一些东西来监控你的事件是否比这个时间长;但除此之外...

于 2012-09-04T14:38:55.797 回答
0

我认为这取决于您是否只是希望调用该方法之间的 X 秒延迟为常数,或者您是否希望每 X 秒调用一次该方法,但如果该方法花费的时间超过 X 秒,则可以允许执行。

您上面的代码将执行前者,其中方法调用之间有一秒钟的延迟,但如果您希望每 X 秒调用一次您的方法,您可能需要考虑使用时间戳DateTime.NowDateTime.Subtract查看自最后一个方法调用。如果系统时钟发生更改,这可能会导致异常行为,例如在夏令时,该方法可能不会运行一个小时,但在您的情况下,这种异常行为可能会被您认为是可以接受的。

于 2012-09-04T15:07:58.423 回答
-1

似乎您遇到的主要问题被描述为“计时器必须在 'DoWork' 执行时'停止',并在方法完成后重新启动”。简而言之,服务需要是多线程的。您应该考虑使用线程池。使用线程池将允许您的执行线程继续计算时间,而后台线程会执行其他一些工作。在此处查看 ThreadPool 文档:http: //msdn.microsoft.com/en-us/library/3dasc8as%28v=vs.80%29.aspx

于 2012-09-04T14:41:38.293 回答