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);
}
}
我看到了日志文件,但没有错误日志
好的,我从哪里开始...
首先,将尽可能少的代码放入构造函数中。初始化服务所需的所有代码都应该在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();
}
}