Windows服务等待计时器,永远不会自行关闭

时间:2019-05-07 07:41:04

标签: c#

我用Visual Studio创建了一个Windows服务项目。此服务应在后台运行,并每X秒轮询一次数据。轮询是通过计时器和滴答事件实现的。因此,每当出现滴答事件时,服务就应该采取措施。

不幸的是,该服务自行关闭,因为它不等待计时器计时。 OnStart方法将执行并运行,但此后服务将自行关闭。

我在程序文件中添加了调试模式

        private static void Main()
        {
#if DEBUG
            new RuntimeService().RunDebugMode();
#else
            ServiceBase.Run(new RuntimeService());
#endif
        }

并将此代码用于我的服务应用程序

public partial class RuntimeService : ServiceBase
{
    private const int BATCH_POLLING_INTERVAL = 3000;

    private Timer batchPollingTimer;

    public RuntimeService()
    {
        InitializeComponent();
    }

    public void RunDebugMode()
    {
        OnStart(null);
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            // ...

            batchPollingTimer = new Timer(BATCH_POLLING_INTERVAL);
            batchPollingTimer.Elapsed += OnTimer;
            batchPollingTimer.Enabled = true;
        }
        catch (Exception exception)
        {
            throw exception;
        }
    }

    protected override void OnStop()
    {
        batchPollingTimer.Enabled = false;

        try
        {
            // ...
        }
        catch (Exception exception)
        {
            throw exception;
        }
    }

    private void OnTimer(object sender, ElapsedEventArgs e)
    {
        batchPollingTimer.Enabled = false;

        // ...

        batchPollingTimer.Enabled = true;
    }
}

如何在不关闭服务并等待计时器计时的情况下运行服务? “关闭自身”是指执行Main方法并忽略计时器。如果需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

它只会在调试模式下执行此操作,因为没有什么可以阻止它结束。通常,除非服务关闭,否则ServiceBase.Run不会返回。添加一段长时间的睡眠,以便在主线程启动计时器后,它将进入睡眠状态,而不是退出主线程

类似的东西:

    private static void Main()
    {
#if DEBUG
        new RuntimeService().RunDebugMode();
        System.Threading.Thread.Sleep(TimeSpan.FromDays(1));
#else
        ServiceBase.Run(new RuntimeService());
#endif
    }

顺便说一句,请考虑将计时器停止/启动置于尝试状态/最后-在OnTimer中发生任何事件的那一刻,停止的计时器将永远不会重新启动,并且您的服务将停止执行任何操作(但可能不会完全崩溃)

private void OnTimer(object sender, ElapsedEventArgs e)
{
  try{
    batchPollingTimer.Enabled = false;

    // ...
  } finally {
    batchPollingTimer.Enabled = true;
  }
}

}