Windows服务在指定时间运行函数

Ziy*_*mad 22 c# windows-services timer

我想启动Windows服务,以便在特定时间每天运行一个功能.

我应该考虑采用什么方法来实现这个?定时器还是使用线程?

小智 70

(1)首次启动时,将_timer.Interval设置为服务启动和调度时间之间的毫秒数.此样本设置的时间表为上午7:00,因为_scheduleTime = DateTime.Today.AddDays(1).AddHours(7);

(2)在Timer_Elapsed上,如果当前间隔不是24小时,则将_timer.Interval重置为24小时(以毫秒为单位).

System.Timers.Timer _timer;
DateTime _scheduleTime; 

public WinService()
{
    InitializeComponent();
    _timer = new System.Timers.Timer();
    _scheduleTime = DateTime.Today.AddDays(1).AddHours(7); // Schedule to run once a day at 7:00 a.m.
}

protected override void OnStart(string[] args)
{           
    // For first time, set amount of seconds between current time and schedule time
    _timer.Enabled = true;
    _timer.Interval = _scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000;                                          
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
}

protected void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    // 1. Process Schedule Task
    // ----------------------------------
    // Add code to Process your task here
    // ----------------------------------


    // 2. If tick for the first time, reset next run to every 24 hours
    if (_timer.Interval != 24 * 60 * 60 * 1000)
    {
        _timer.Interval = 24 * 60 * 60 * 1000;
    }  
}
Run Code Online (Sandbox Code Playgroud)

编辑:

有时人们希望将服务安排在第0天开始,而不是明天开始,以便他们更改DateTime.Today.AddDays(0).如果他们这样做并在过去设置时间,则会导致错误,将Interval设置为负数.

//Test if its a time in the past and protect setting _timer.Interval with a negative number which causes an error.
double tillNextInterval = _scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000;
if (tillNextInterval < 0) tillNextInterval += new TimeSpan(24, 0, 0).TotalSeconds * 1000;
_timer.Interval = tillNextInterval;
Run Code Online (Sandbox Code Playgroud)

  • 如果您希望它在特定时间点运行,而不是使其成为服务,您可以考虑将其设置为普通的控制台应用程序,并使用Windows任务计划程序运行它 (3认同)
  • 看起来你提供了一个很好的代码示例.添加一些围绕它的代码的解释将有助于专门解决用户的问题. (2认同)
  • 我想如果任务执行时间很长,下次就不会正好在7点运行了。它将继续增长。 (2认同)

Jak*_*icz 7

您确定需要一项每天仅运行一次的服务吗?

也许 Windows 任务计划会是更好的解决方案?


Eva*_*van 7

很好的答案(我使用了你的代码),但这一行有一个问题:

_timer.Interval = _scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000;
Run Code Online (Sandbox Code Playgroud)

如果DateTime.now晚于scheduleTime,您将变为负数,这将在分配给timer.Interval时生成异常.

我用了:

if (DateTime.now > scheduleTime)
    scheduleTime = scheduleTime.AddHours(24);
Run Code Online (Sandbox Code Playgroud)

然后做减法.