2010-11-26 7 views
2

Ich habe einen Windows-Dienst behandelt Ereignisse ausgelöst durch einen System.Timers.Timer. Ich möchte das Intervall dieses Timers auf 3 Monate einstellen.Timer mit Intervall von mehreren Monaten

Die Interval-Eigenschaft des System.Timers.Timer ist ein Int32 in Millisekunden und Int32.MaxValue ist kleiner als 3 Monate in Millisekunden.

Was soll ich tun?

Antwort

10

Sie würden Ihr Design überdenken. Speichern Sie das nächste Mal, wenn Sie Ihr Ereignis ausführen möchten (z. B. Registrierung, Datei, Datenbank, ...), und wachen Sie dann regelmäßig auf, um zu überprüfen, ob diese Zeit verstrichen ist. Selbst wenn Sie einen System.Timers.Timer für 3 Monate einstellen könnten, würde das System wahrscheinlich neu starten, bevor der Timer abgelaufen ist und Sie Ihr Ereignis verlieren würden.

Eine andere Option wäre die Verwendung eines geplanten Jobs, der vom Windows Scheduler ausgeführt wird. Es würde ein kleines Programm ausführen, das Ihrem Dienst eine Nachricht sendet, die besagt, dass das Ereignis aufgetreten ist. Dies wäre weniger aufwändig - wenn auch komplexer - als periodisch zu wachen, um zu überprüfen, ob die 3 Monate verstrichen sind.

+0

Design neu gedacht, und jetzt überprüft ein Timer eine NextExecuteTime-Eigenschaft. Danke für Ihre Hilfe. –

+0

Ich bin froh, dass ich helfen konnte. –

1

Sie können Ihren PC 3 Monate lang nicht ununterbrochen laufen lassen. Wenn die Anwendung geschlossen ist, wird der Timer ebenfalls geschlossen. Beim Neustart der Anwendung wird der Timer neu gestartet.

Wenn Sie das Ereignis in einem Intervall von 3 Monaten auslösen möchten, müssen Sie Informationen über die Gesamtzeit speichern, die vom Timer zum Zeitpunkt des Beendens der Anwendung verstrichen ist.

Aktualisiert

So haben Sie Ihr Intervall in einigen Teilen aufzuteilen und einen Zähler auf jeden Satz verstreichen und Schritt it.Check es jeder in verstreichen, bis er zu 3 Monaten erreicht.

z.B.

int interval = 10 * 24 * 60 * 60 * 1000; // Time interval for 10 days 
    int counter = 0; 
    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     counter++; 
     if (counter == 9) 
     { 
      //do your task for 3 months 
      //since counter increments 9 times at interval of 10 days 
      //so 9*10=90 days i.e. nearly equal to 3 months 
      counter = 0; 
     } 
    } 
+2

Wie ich bereits erwähnt habe, ist dies für einen Windows-Dienst, nicht für eine Anwendung, und so erwarte ich, dass dieser Dienst kontinuierlich für mehrere Monate läuft. Vielen Dank für Ihren Kommentar. –

+1

Erwarten Sie wirklich, dass eine Windows-Maschine mehr als 3 Monate zuverlässig bleibt? Auch ohne Abstürze werden kritische Sicherheitsupdates veröffentlicht, die alle paar Monate einen Neustart erfordern. Sehen Sie sich die Uptime-Statistiken http://uptime.netcraft.com/up/today/top.avg.html und http://uptime.netcraft.com/up/today/requested.html an. Viele Systeme haben ihre Betriebszeiten in Wochen und die besten in Monaten gemessen. –

+0

@JamesKovacs Das ist irrelevant, wenn der Timer so eingestellt ist, dass er an einem bestimmten _vorberechneten Datum_ auslöst. Es braucht nur eine Zeit _span_. Sie möchten, dass ein System bei Ausfallzeiten und Neustarts nur richtig funktioniert? – Nyerguds

0

Ich würde eine exe-Anwendung erstellen und als Teil des geplanten Windows Task ausgeführt werden.

1

Ich würde Quartz.net verwenden - der Open-Source-Enterprise Job Scheduler - http://quartznet.sourceforge.net/

Sie CRON verwenden können wie Syntax- http://quartznet.sourceforge.net/tutorial/lesson_6.html & relevanten Jobstatus auf eine DB (nur leicht speichern kann Incase die Maschine stirbt, die es wird) - http://quartznet.sourceforge.net/tutorial/lesson_9.html, und viel mehr Nützlichkeit.

Ich habe Quartz.net auf mehreren Produktionssystemen und meines Wissens werden die Prozesse noch heute laufen :)

Warum System.Timer nicht verwenden - http://quartznet.sourceforge.net/faq.html#whynottimer

Viel Glück!

0

Hatte das gleiche Problem, außer dass es ein generisches System war, das dasselbe mit vollständig einstellbaren Intervallen von Millisekunden bis zu Monaten tun konnte. Nun, war angenommen zu. Es stellte sich heraus, dass es in der Tat in Intervallen von mehr als 24,8 Tagen aufgrund dessen versagte.

In meinem Fall war das "Überdenken des Ansatzes" außer Frage, da es nur ein kleines Problem Sub-Fall eines viel größeren Windows-Dienstsystems war.

Die Lösung war ziemlich einfach, aber beachten Sie, dass ich ein Seitensystem hatte, das mich mit der nächsten Ausführung als DateTime lieferte; Der Job des Zeitgebers bestand nur darin, das zu erreichen, um die Aufgabe tatsächlich auszuführen, also berechnete er das Intervall, indem er einfach DateTime.Now davon abzog.

In diesem Fall alles, was ich tun musste, war neben meinem Timer-Objekt einen Überlauf boolean zu halten, und Einstellung, dass, wenn dieses Intervall gegen Int32.MaxValue Überprüfung:

private Timer _timer; 
private Boolean _overflow; 

private void QueueNextTime(DateTime thisTime) 
{ 
    TimeSpan interval = this.GetNextRunTime(thisTime) - DateTime.Now; 
    Int64 intervalInt = (Int64)((interval.TotalMilliseconds <= 0) ? 1 : interval.TotalMilliseconds); 
    // If interval greater than Int32.MaxValue, set the boolean to skip the next run. The interval will be topped at Int32.MaxValue. 
    // The TimerElapsed function will call this function again anyway, so no need to store any information on how much is left. 
    // It'll just repeat until the overflow status is 'false'. 
    this._overflow = intervalInt > Int32.MaxValue; 
    this._timer.Interval = Math.Min(intervalInt, Int32.MaxValue); 
    this._timer.Start(); 
} 

// The function linked to _timer.Elapsed 
private void TimerElapsed(object sender, ElapsedEventArgs e) 
{ 
    this._timer.Stop(); 
    if (this._overflow) 
    { 
     QueueNextTime(e.SignalTime); 
     return; 
    } 

    // Execute tasks 
    // ... 
    // ... 

    // schedule next execution 
    QueueNextTime(e.SignalTime); 
} 

Dies vereinfacht, natürlich; Das reale System hat try/catch und ein System, um externe Stoppbefehle abzubrechen. Aber das ist der Kern davon.