Piszę usługę Windows, która będzie przetwarzać "coś" co kilka minut.Zachowanie timera, gdy wykonanie trwa dłużej niż zakres?
Oto kod:
public Service()
{
this.InitializeComponent();
this.ServiceName = Name;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.eventLog.Source = Name;
// initialize timer
this.timer.Elapsed += this.TimerElapsed;
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
eventLog.WriteEntry("Starting syncronization...", EventLogEntryType.Information);
if (this.processor.PrepareToRun())
{
this.processor.Run();
}
}
Zastanawiam się, co się stanie, jeśli this.processor.Run()
zajmie dużo czasu i następny TimerElapsed
zdarzenie zostanie podniesiona? Czy to pominie? Czy po zakończeniu będzie czekać i działać jak najszybciej? Czy powinienem rozważyć te scenariusze i kod dla nich?
Używam System.Timers.Timer
EDIT:
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
eventLog.WriteEntry("Starting syncronization...", EventLogEntryType.Information);
try
{
this.timer.Stop();
if (this.processor.PrepareToRun())
{
this.processor.Run();
}
}
catch (Exception ex)
{
LoggingAndNotifications.LogAndNotify(ex);
}
finally
{
this.timer.Start();
}
}
EDIT 2
public Service()
{
this.InitializeComponent();
this.ServiceName = Name;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.eventLog.Source = Name;
// initialize timer
this.timer.AutoReset = false;
this.timer.Elapsed += this.TimerElapsed;
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
eventLog.WriteEntry("Starting syncronization...", EventLogEntryType.Information);
try
{
if (this.processor.PrepareToRun())
{
this.processor.Run();
}
}
catch (Exception ex)
{
LoggingAndNotifications.LogAndNotify(ex);
throw;
}
finally
{
this.timer.Start();
}
}
Lubię # 4 w mojej konkretnej sytuacji. Czy moja edycja (w oryginalnym wpisie) wygląda poprawnie, jeśli chcę tego scenariusza? – katit
Zatrzymanie licznika czasu nie pomoże, przedłużenie sesji obsługi zdarzenia może być opóźnione, jeśli w procesie jest dużo aktywnych wątków TP. Ustaw właściwość AutoReset na wartość false. –
Byłbym bardzo ostrożny z 2. 1 albo wyraźnie działa, albo nie, ale jest wspaniały, kiedy naprawdę potrzebujesz go co X minut. Różnica między 3 a 4 wynosi pomiędzy "co x minut z kilkoma pominiętymi" i "co x minut po ostatnim zakończeniu". Oba mają swoje miejsce i często albo wszystko jest w porządku. Nie musisz '.Stop()' zegara, jest to łatwiejsze i bezpieczniejsze (w niektórych przypadkach niektóre dziwaczne przypadki oznaczają, że nawet nie posunąłeś się tak daleko), aby nie był to automatyczny reset. Ustaw "AutoReset" na false lub użyj System.Threading.Timer z okresem 'Timeout.Infinite'. –