【问题标题】:Using a timer in a long running windows service在长时间运行的 Windows 服务中使用计时器
【发布时间】:2013-05-15 09:51:45
【问题描述】:

我正在尝试在 Windows 服务中使用计时器。该服务能够启动和停止,并且在发生这种情况时我会在事件日志中写入一些内容,这很有效。我的问题是,我还想使用一个持续运行的计时器,并在每次触发 timeElapsed 事件时向事件日志写入一些内容。

编辑:(我更改了代码,所以计时器是一个字段,但仍然不是我期望的结果,事件日志中没有日志条目)

using System.Timers;

初始化服务:

    public Timer timer;

    public MonitorService()
    {
        InitializeComponent();
        timer = new Timer(10000);
        //Some code that really doesn't matter
    }

开始事件

    protected override void OnStart(string[] args)
    {
        // Hook up the Elapsed event for the timer.
        timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        timer.Enabled = true;

        timer.Start();

        EventLogger.WriteEntry("Biztalk monitoring service started", EventLogEntryType.SuccessAudit);

        // If the timer is declared in a long-running method, use
        // KeepAlive to prevent garbage collection from occurring
        // before the method ends.
        // GC.KeepAlive(timer);
    }


    private int count =0;

定时事件: (这是行不通的,没有每 10 秒写入事件日志的条目,而我希望它这样做)

    // Specify what you want to happen when the Elapsed event is 
    // raised.
    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        //Some other code that doesn't mather
        count++;
        EventLogger.WriteEntry(string.Format("TimerEvent has ran {0} times. Total time is: {1}", count, e.SignalTime), EventLogEntryType.Information);
    }

on stop 事件:

    protected override void OnStop()
    {
        EventLogger.WriteEntry("Biztalk monitoring service stopped", EventLogEntryType.Warning);
    }

主要

对于那些想知道这是我在 Program.cs 中的主要方法的人:

     ///<summary>
     ///The main entry point for the application.
     ///</summary>
    static void Main()
    {
        var servicesToRun = new ServiceBase[] 
            { 
                new MonitorService() 
            };
        ServiceBase.Run(servicesToRun);
    }

已经问过了?确实是的!

我知道这个问题之前已经被问过,就像这里一样:Windows service with timer AND Best Timer for using in a Windows service

但这些解决方案似乎无法解决我的问题。

欢迎提出任何建议!

【问题讨论】:

  • 我强烈建议您不要使用System.Timers.Timer,因为它会吞下异常,隐藏错误。如果您的 Elapsed 事件发生异常,您永远不会知道。见blog.mischel.com/2011/05/19/…。您应该 1) 使用 try/catch 保护您的事件处理程序,以及 2) 使用 System.Threading.Timer
  • @JimMischel 我刚刚发现这实际上是我的问题,现在我看到了你的评论。它只是在吞下一个例外,并且在那里它不起作用。 System.Threading.Timer 能解决这一切吗?
  • System.Threading.Timer 不会吞下异常,这会让你知道你的处理程序有问题。真正的解决方案是非常小心地处理计时器事件处理程序中的异常。
  • System.Threading.Timer 是否会在事件日志中写入一些内容,或者它如何让我知道我什么时候不调试?
  • 不,它不会写入事件日志。但是,如果您的 OnTimedEvent 方法中未处理异常,您的程序将崩溃,这表明存在问题。另一方面,System.Timers.Timer 只是压制异常并继续,就好像什么都没发生一样。 System.Threading.Timer 并不能让您不必处理异常。它只是不会阻止您找出何时引发异常。

标签: c# .net-4.0 timer windows-services


【解决方案1】:

你的计时器是 OnStart 方法的本地。不应该。它应该是你的服务类的一个字段,所以你不需要使用提示来欺骗垃圾收集器。

编辑: 你没有指定你的usings。确保使用 Timer 时您使用的是 System.Timers.Timer不是 System.Windows.Forms.Timer

【讨论】:

  • 哦,是的,你是对的,甚至没有注意到这一点,同时专注于其他可能错误的事情!去试试吧!
  • 我用你的解决方案编辑了我的问题,但它仍然不起作用。
  • 我很确定我正在使用那个,我会将它添加到我的问题中
  • 我接受了这个,因为我的问题已经解决了,这个答案说明了其中一个问题,但是请记住,Jim Mischel 的评论也很重要!
【解决方案2】:

如果您想在设定的时间段后将某些内容记录到事件日志(除了您正在使用的计时器的经过事件中所做的事情),您可以在服务级别使用另一个计时器并注册其经过的事件.在这种情况下,您可以记录任何您想要的内容。

正如 nvoigt 所说,您也应该将此计时器移至服务级别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 2019-08-01
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    相关资源
    最近更新 更多