每天早上6点运行一次的Windows服务调度

16

我创建了一个Windows服务,希望该服务每天上午6:00定期运行。 以下是我编写的代码:

public Service1()
{
    InitializeComponent();
}

protected override void OnStart(string[] args)
{
    try
    {
        ExtractDataFromSharePoint();
    }
    catch (Exception ex)
    {
        //Displays and Logs Message
        _loggerDetails.LogMessage = ex.ToString();
        _writeLog.LogDetails(_loggerDetails.LogLevel_Error, _loggerDetails.LogMessage);
    }
}
在上面的代码中,您可以看到在服务的OnStart方法中我调用了一个ExtractDataFromSharePoint()函数。如何安排它每天早上6:00运行?
在上述代码中,您可以看到在服务的OnStart方法中,我调用了ExtractDataFromSharePoint()函数。我该如何将其安排为每天早上6:00运行?

1
可能是重复的问题: 如何在C#中安排一个Windows服务每天执行一个任务? - Pierre-Luc Pineault
7个回答

16

这里,您有两种方法使您的应用程序每天在早上6点运行。

1)创建一个控制台应用程序,并通过Windows计划程序在早上6点执行。

2)在您的Windows服务中创建一个计时器(System.Timers.Timer),它将在每个定义的间隔时间内执行,在您的函数中,您需要检查系统时间是否为早上6点,然后执行您的代码。

ServiceTimer = new System.Timers.Timer();
ServiceTimer.Enabled = true;
ServiceTimer.Interval = 60000 * Interval;
ServiceTimer.Elapsed += new System.Timers.ElapsedEventHandler(your function);

注意:在您的函数中,您需要编写代码仅在上午6点执行您的方法,而不是每次都执行。


这可能不会每天在6:00执行,因为如果我们设置了一个间隔,可能没有小时与06小时重合。 - Jinith
3
你好Jinith, 在这种情况下,你需要在函数中编写逻辑,例如:如果 (System.DateTime.Now() >= 6 且 LastExecutionDateTime.Date == Today.Date) { LastExecutionDateTime = System.DateTime.Now();// 在这里添加其他代码。} - Rachit Patel
你认为这种方式使用怎么样?ServiceTimer.Interval = TimeSpan.FromMinutes(1).TotalMilliseconds; - Luiz Fernando Corrêa Leite

10

这是一段代码,将在每天早上6点在服务中运行。

包括:

using System.Threading;

同时确保你在类内声明计时器:

private System.Threading.Timer _timer = null;

下面的StartTimer函数接受一个开始时间和一个间隔周期,目前设置为从早上6点开始,每24小时运行一次。如果需要,您可以轻松更改它以在不同的时间和时间间隔启动。

 protected override void OnStart(string[] args)
    {
        // Pass in the time you want to start and the interval
        StartTimer(new TimeSpan(6, 0, 0), new TimeSpan(24, 0, 0));

    }
    protected void StartTimer(TimeSpan scheduledRunTime, TimeSpan timeBetweenEachRun) {
        // Initialize timer
        double current = DateTime.Now.TimeOfDay.TotalMilliseconds;
        double scheduledTime = scheduledRunTime.TotalMilliseconds;
        double intervalPeriod = timeBetweenEachRun.TotalMilliseconds;
        // calculates the first execution of the method, either its today at the scheduled time or tomorrow (if scheduled time has already occurred today)
        double firstExecution = current > scheduledTime ? intervalPeriod - (current - scheduledTime) : scheduledTime - current;

        // create callback - this is the method that is called on every interval
        TimerCallback callback = new TimerCallback(RunXMLService);

        // create timer
        _timer = new Timer(callback, null, Convert.ToInt32(firstExecution), Convert.ToInt32(intervalPeriod));

    }
    public void RunXMLService(object state) {
        // Code that runs every interval period
    }

1
请将以下与编程相关的内容从英文翻译为中文。只返回翻译后的文本:请将此更正为double firstExecution = current > scheduledTime ? intervalPeriod - (current - scheduledTime) : scheduledTime - current;这将确保在下一个间隔内正确运行。 - Farukh Zahoor
如之前的评论所提到的,@cmartin,请将intervalPeriod +(current - scheduledTime)更改为intervalPeriod -(current - scheduledTime),否则会延迟开始时间。 - Peru

10

你无需使用服务实现此功能。只需创建一个常规控制台应用程序,然后使用Windows计划任务程序在早上6点运行您的程序即可。 服务是当您需要程序一直运行时使用的。


7
感谢 @Rachit 的回答,现在我能够满足我的要求了。
static  System.Timers.Timer _timer;
static string _ScheduledRunningTime ="6:00 AM";
public Service1()
{
    InitializeComponent();
}

protected override void OnStart(string[] args)
{
    try
    {
        _timer = new System.Timers.Timer();
        _timer.Interval = TimeSpan.FromMinutes(1).TotalMilliseconds;//Every one minute
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        _timer.Start();
    }
    catch (Exception ex)
    {
        //Displays and Logs Message
        _loggerDetails.LogMessage = ex.ToString();
        _writeLog.LogDetails(_loggerDetails.LogLevel_Error, _loggerDetails.LogMessage);
     }
 }

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    //Displays and Logs Message
    _loggerDetails.LogMessage = "timer_Elapsed method at :"+DateTime.Now ;
    _writeLog.LogDetails(_loggerDetails.LogLevel_Info, _loggerDetails.LogMessage);

    string _CurrentTime=String.Format("{0:t}", DateTime.Now);
    if (_CurrentTime == _ScheduledRunningTime)
    {
        ExtractDataFromSharePoint();
    }
}

1

0
这里是调用数据库并根据结果设置调度时间的代码:
此外,您还可以在此处调用多个API调用,以发送定期的短信/电子邮件。
public void ScheduleService()
    {
        try
        {
            dsData = new DataSet();
            _timeSchedular = new Timer(new TimerCallback(SchedularCallBack));
            dsData = objDataManipulation.GetInitialSMSConfig();
            if (dsData.Tables[0].Rows.Count > 0)
            {                    
                DateTime scheduledTime = DateTime.MinValue;
                scheduledTime = DateTime.Parse(dsData.Tables[0].Rows[0]["AUTOSMSTIME"].ToString());
                if (string.Format("{0:dd/MM/YYYY HH:mm}", DateTime.Now) == string.Format("{0:dd/MM/YYYY HH:mm}", scheduledTime))
                {
                    objDataManipulation.WriteToFile("Service Schedule Time Detected");
                    for (int iRow = 0; iRow < dsData.Tables[0].Rows.Count; iRow++)
                    {
                            if (dsData.Tables.Count > 1)
                            {
                                if (dsData.Tables[1].Rows.Count > 0)
                                {
                                    sendData(dsData);
                                }
                            }
                            else
                            {
                                objDataManipulation.WriteToFile("No SMS Content Data !");
                            }                        }
                }
                if (DateTime.Now > scheduledTime)
                {
                    scheduledTime = scheduledTime.AddDays(1);
                }                   
                TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
                string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

                objDataManipulation.WriteToFile("TexRetail Service scheduled to run after: " + schedule + " {0}");
                int dueTime = Convert.ToInt32(timeSpan.TotalMilliseconds);
                //Change the Timer's Due Time.
                _timeSchedular.Change(dueTime, Timeout.Infinite);                    
            }
        }
        catch (Exception ex)
        {                              
            objDataManipulation.WriteToFile("Service Error {0}" + ex.Message + ex.StackTrace + ex.Source);
            using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController(ServiceName))
            {
                serviceController.Stop();
            }
        }
    }

0

实际上我正在从 app.config 文件中获取时间间隔

   protected override void OnStart(string[] args)
    {            
        Timer timer = new Timer();
        this._dbServiceInterval = int.Parse(ConfigurationManager.AppSettings["ServiceInterval"].ToString());
        timer.Interval = (double)this._dbServiceInterval;
        timer.Enabled = true;
        timer.Start();
        timer.Elapsed += new ElapsedEventHandler(this.timerDispatcher_Elapsed);
    }

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