如何让一个函数在服务中每10分钟运行一次?

8

我有一个正在运行的Windows服务,在其中我想每10分钟运行一次函数。我找到了一些代码,但似乎不起作用?我有一个记录器,它似乎从未进入timer_Elapsed函数?

 protected override void OnStart(string[] args)
    {
       // SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
       // test.Import();
         log.Info("Info - Service Started");
        _timer = new Timer(10 * 60 * 1000); // every 10 minutes??
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    }

    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        log.Info("Info - Check time");
        DateTime startAt = DateTime.Today.AddHours(9).AddMinutes(48);
        if (_lastRun < startAt && DateTime.Now >= startAt)
        {
            // stop the timer 
            _timer.Stop();               

            try
            {
                log.Info("Info - Import");
                SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
                test.Import();
            }
            catch (Exception ex) {
                log.Error("This is my error - ", ex);
            }

            _lastRun = DateTime.Now;
            _timer.Start();
        }
    }

1
你需要在计时器上调用start吗? - David Z.
请查看以下链接,了解关于Windows服务和计时器的更多信息:https://dev59.com/DHVC5IYBdhLWcg3wlyMo - Andras Zoltan
为什么?DateTime.Today.AddHours(9).AddMinutes(48); - Vijay Singh Rana
5个回答

20
你需要启动计时器:
protected override void OnStart(string[] args)
{
     log.Info("Info - Service Started");
    _timer = new Timer(10 * 60 * 1000); // every 10 minutes
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    _timer.Start(); // <- important
}

6
我更喜欢使用 TimeSpan.FromMinutes(10).TotalMilliseconds; 而不是 10 * 60 * 1000 来表示10分钟的时间间隔。该表达方式更简洁、易读且减少了错误的可能性。 - Jaider

4

我没有看到 _timer.Start(),那应该就是你的问题。


3

Daniel Hilgarth 是正确的 - 主要问题在于您从未调用计时器上的Start方法。

话虽如此,您可能还想考虑使用Windows任务计划程序而不是具有定时器的服务。这样可以使您安排任务每10分钟运行一次,但也可以随时更改时间表,而无需编译更改。


3

我也需要这个功能。也就是说,我的C# Windows服务必须每隔10分钟检查电子邮件。为了使代码更有效,我精简了一些逻辑,如下:

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            _timer.Stop();
            try
            {
                EventLog.WriteEntry(Program.EventLogName, "Checking emails " + _count++);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry(Program.EventLogName, "This is my error " + ex.Message);
            }
            _timer.Start();
        }

timer_elapsed方法确实会在第一次_timer.start()后每10分钟调用一次,你顺便错过了这个。我还没有检查_lastRun和startAt。我认为我们不需要它。


1

尝试启动计时器

protected override void OnStart(string[] args)
    {
       // SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
       // test.Import();
         log.Info("Info - Service Started");
        _timer = new Timer(10 * 60 * 1000); // every 10 minutes??
            _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
    }

    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        log.Info("Info - Check time");
        DateTime startAt = DateTime.Today.AddHours(9).AddMinutes(48);
        if (_lastRun < startAt && DateTime.Now >= startAt)
        {
            // stop the timer 
            _timer.Stop();               

            try
            {
                log.Info("Info - Import");
                SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
                test.Import();
            }
            catch (Exception ex) {
                log.Error("This is my error - ", ex);
            }

            _lastRun = DateTime.Now;
            _timer.Start();
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接