Windows 服务在 3 小时后未找到

本文关键字:小时 服务 Windows | 更新日期: 2023-09-27 18:33:09

我有一个Windows服务,这个服务每x秒或每分钟,应该执行一个任务。我已经编写了此服务,将其安装在我的SO(Windows 7)上,因此它可以工作三个小时,然后服务状态为"正在运行",但它已停止执行任务。我认为,计时器处于崩溃状态。

这是一个代码:

            public Service1()
            {
                InitializeComponent();
                if (!System.Diagnostics.EventLog.SourceExists("AutomaticallyRunScript"))
                {
                    System.Diagnostics.EventLog.CreateEventSource(
                        "AutomaticRunScript", "LoggerAutomaticRunScript");
                }
                log.Info("preparazione file di config in corso...");
                //set parameter from config File
                setParameterFromAppConfig();
                 // get today's date at hours:minutes   
                 DateTime tenAM = DateTime.Today.AddHours(hours);
                 tenAM = tenAM.AddMinutes(minutes);
                 int timeToFirstExecution = 0;
                 // if hours:minutes has passed, get tomorrow at hours:minutes     
                 if (DateTime.Now > tenAM)
                     tenAM = tenAM.AddDays(1);//add 1 day of data
                 // calculate the number of milliseconds in hoursFrequency, minutesFrequency, secondsFrequency time.    
                 int timeBetweenCalls = (int)new TimeSpan(hoursFrequency,
                     minutesFrequency, secondsFrequency).TotalMilliseconds;
                 // if hours:minutes has passed, get tomorrow at hours:minutes 
                 //only if the frequency of the run script is every day
                 if (DateTime.Now > tenAM && hoursFrequency == 24)
                 {
                     tenAM = tenAM.AddDays(1);//add 1 day of data
                     // calculate milliseconds until the next hours:minutes   .   
                     timeToFirstExecution = (int)tenAM.Subtract(DateTime.Now).TotalMilliseconds;
                 }
                 else
                 {
                     timeToFirstExecution = (int)DateTime.Now.AddMilliseconds(timeBetweenCalls).Subtract(DateTime.Now).TotalMilliseconds;
                 }
                 // set the method to execute when the timer executes.    
                 TimerCallback methodToExecute = ProcessFile;

  // start the timer.  The timer will execute "ProcessFile" when the number of seconds between now and    
             // the next hours:minutes elapse.  After that, it will execute every 24 hours.    
             System.Threading.Timer timer = new System.Threading.Timer(methodToExecute, null, timeToFirstExecution, timeBetweenCalls);
             // Block the main thread forever.  The timer will continue to execute.    
             //Thread.Sleep(Timeout.Infinite);
        }
protected override void OnStart(string[] args)
{
   //
}
protected override void OnStop(string[] args)
{
   //
}
        public void ProcessFile(object obj)
        {
            try
            {
                // do your processing here. 
                String percorsoFiles = ConfigurationManager.AppSettings["NameFileBat"];
                string[] percorsoFile = percorsoFiles.Split(';');
                foreach (string filebatch in percorsoFile)
                {
                    //log.Info(": EXECUTE BATCH FILE " + filebatch + " NOW");
                    EventLog.WriteEntry("EXECUTE BATCH FILE " + filebatch + " NOW", EventLogEntryType.Information);
                    System.Diagnostics.Process.Start(filebatch);
                    //System.Threading.Thread.Sleep(elapsedTimeBetween2BatchFile);
                }
                EventLog.WriteEntry("***FINISHED***", EventLogEntryType.Information);
                //log.Info("***FINISHED***");
            }
            catch (Exception e)
            {
                EventLog.WriteEntry("error, see log file ", EventLogEntryType.Error);
                log.Error("errore: " + e);
            }
        }

我看到了日志文件,但没有错误日志

Windows 服务在 3 小时后未找到

好的,我从哪里开始...

首先,将尽可能少的代码放入构造函数中。初始化服务所需的所有代码都应该在OnStart中,停止服务所需的所有代码(即停止计时器的代码)都应该在OnStop中。这是第一件事。

然后,最好在计时器事件

正在执行时停止计时器,并在计时器事件结束时在 finally 块中重新启动计时器。

第三,我建议不要使用System.Threading.Timer而是System.Timers.Timer它更容易处理并允许"一次性"计时器,这会迫使您在代码中重新启动计时器。这里可能出错的事情更少。

另外,永远不要将计时器创建为局部变量!在方法失焦后,他们可能会随时被垃圾收集。

为什么每个人都使用ConfigurationManager.AppSettings,而编写Properties.Settings.Default.NameFileBat更容易且不易出错?


如何在服务中使用System.Timers.Timer的简短示例:

private System.Timers.Timer myTimer;
protected override void OnStart(string[] args)
{
    myTimer = new Timer(5000);          // Every 5 seconds
    myTimer.AutoReset = false;          // Only 1 event!!
    myTimer.Elapsed += TimerElapsed;    // Event handler
    myTimer.Start();                    // Start the timer
}
protected override void OnStop()
{
    myTimer.Stop();
    myTimer = null;
}
privated void TimerElapsed(object source, ElapsedEventArgs e)
{
    try
    {
        // Do stuff
    }
    finally
    {
        // Restart if timer variable is not null
        if (myTimer != null)        
            myTimer.Start();
    }
}