Ich erstelle einen Scheduler, um Ereignisse zu bestimmten Tageszeiten auszulösen, und dazu spanne ich Aufgaben (einzeln, dh nur den nächsten) mit einer Task.Delay von allem nach oben zu ein paar Tagen Verspätung. Zum Beispiel, nachdem das letzte Ereignis an einem Freitagnachmittag ausgelöst wurde, richte ich das nächste Ereignis ein, das am Montag stattfinden wird. Es könnte also ein TimeSpan von bis zu 3 Tagen sein (~ 260.000.000 Millisekunden).Ist es akzeptabel, Aufgaben mit langen Verzögerungen zu erstellen?
Ist das akzeptabel? Ich bin besorgt, dass dies für eine Produktionsumgebung nicht stabil genug sein wird.
Hier einige Code-Schnipsel zu beschreiben, was ich habe zusammen:
private void SetNextEvent()
{
TimeModel next = GetNextScheduledTime();
Debug.WriteLine($"Next schedule [{next.TimeType}]: {next.Time.ToString("yyyy-MM-dd HH:mm:ss")}");
TimeSpan delay = next.Time.Subtract(DateTime.Now);
Task.Run(async() =>
{
await Task.Delay(delay);
FireEvent(next);
});
}
private void FireEvent(TimeModel time)
{
Debug.WriteLine($"Event fired [{time.TimeType}]: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
OnSchedulerEvent?.Invoke(this, new SchedulerEventArgs { ScheduleType = time.TimeType });
if (_running)
SetNextEvent();
}
Kann es funktionieren? Ich nehme an. Der erste Gedanke ist, dass wenn der Server neu gestartet werden muss, Sie ohne dauerhaften Zustand abgespritzt werden. Es gibt viele Scheduler wie [Quartz] (http://www.quartz-scheduler.net/), die speziell dafür entwickelt wurden. Ich denke, dass sie eine stärkere Entscheidung wären. –
Wenn der Server neu gestartet wird, wird der Dienst neu gestartet, es wird SetNextEvent aufgerufen, das dieselbe nächste geplante Zeit zurückgibt, und eine Aufgabe mit einem TimeSpan von diesem Punkt aus ... Ich habe Quartz in Betracht gezogen, aber für was ich kann in diesen beiden Methoden erreichen, schien es ein bisschen übertrieben. – Detail
Sie sollten nach einer negativen 'TimeSpan-Verzögerung 'suchen, vorausgesetzt, das Verhalten von' GetNextScheduledTime' bleibt gleich, bis FireEvent erfolgreich ausgeführt wird. Da kann es zu einem Problem kommen, dass die Uhr die nächste geplante Zeit überschreitet, während der Server neu gestartet wird. Schlimmer noch, es schaffte es, genau -1 Millisekunden zu erreichen, "Task.Delay" endet nie. – ShuberFu