【问题标题】:windows service wait for timer and never close on its ownWindows服务等待计时器并且永远不会自行关闭
【发布时间】:2019-05-07 07:41:03
【问题描述】:

我使用 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 方法并忽略计时器。如果您需要更多信息,请告诉我。

【问题讨论】:

  • “不幸的是服务关闭了”,你的意思是服务被关闭了?通过它自己?容错配置重启?服务是否在 sys 日志中遇到错误?还是Service在打勾前退出调试模式?
  • “关闭自身”是指执行 Main 方法并忽略计时器

标签: c#


【解决方案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
    }

顺便说一句,考虑将您的计时器停止/启动放在 try/finally 中 - 目前,如果您的 OnTimer 发生某些事情,您停止的计时器将永远不会重新启动,您的服务将停止执行任何操作(但可能不会完全崩溃)

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

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

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 2019-12-21
    • 2021-08-05
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多