DelayedCall class
Very easy asynchronous delayed function calls. Typesafe invocation of nearly any method through generic parameters. Delayed calls can be cancelled, pulled forward or repeated later.
The DelayedCall class lets you implement deferred actions without the need to care about the timer handling yourself. Therefore, many methods for controlling the invocation are available, like to prematurely stop the timer, reset or change the delay, repeat the delayed call with the same or a different timeout, or determining whether the timer is still waiting to trigger.
Actions can be started in the same thread as the timer was started, or asynchronously in another thread. The first option is required to abe able to use the DelayedCall class in GUI environments like Windows Forms or WPF.
Compatibility:
Example
The following sample code shows how the DelayedCall class can be used:
// This is not required for normal operation.
private DelayedCall dc;
private void button1_Click(object sender, EventArgs e)
{
// Change button text in 2 seconds
dc = DelayedCall<string>.Start(SetButtonText, "I was clicked", 2000);
}
private void SetButtonText(string newText)
{
button1.Text = newText;
}
private void HurryUpButton_Click(object sender, EventArgs e)
{
// Invoke SetButtonText now, if the timeout isn't elapsed yet
if (dc != null) dc.Fire();
// Prepare a new DelayedCall object for later use
DelayedCall exitDelay = DelayedCall.Create(Application.Exit, 0);
// Now start the timeout with 0.5 seconds
exitDelay.Reset(500);
}
Download
DelayedCall.cs30.1 KiBSource code of the DelayedCall class
Previous versionsChanges
SupportsSynchronization
-Eigenschaft hinzugefügt. Kompatibilitäts-Code aus 2007 in neueren Versionen entfernt; diese Version bleibt unverändert verfügbar.
Cancel
-Aufrufen durch Prüfung eines Abbruchflags unmittelbar vor dem Aufruf der Zielmethode.
- Die alte Aufrufmethode mit dem new-Operator wurde durch statische Methoden ersetzt, die jetzt gleich im Namen unterscheiden, ob man den Aufruf nur vorbereiten oder gleich starten möchte (
Create
,Start
). Die alte Aufrufmethode ist noch als „veraltet“ zugelassen, sodass die Klasse kompatibel sein sollte. - Durch die Verwendung von generischen Unterklassen lassen sich Methoden mit bis zu 3 Parametern typsicher und ohne Wrapper-Funktion und Typkonvertierungen von object aufrufen. Nur Rückgabewerte dürfen sie nicht haben, die könnten aber ohnehin nicht verarbeitet werden. Eine Unterstützung für solche Funktionen ließe sich aber auch nachrüsten, ebenso wie die Unterstützung für mehr Parameter.
- Methodenaufrufe sind jetzt auch asynchron, d. h. in einem ThreadPool-Thread möglich. Dafür gibt es zusätzliche Methoden (
CreateAsync
,StartAsync
), die statt dem System.Windows.Forms.Timer einen System.Timers.Timer verwenden. Ansonsten wird die Methode auch weiterhin im Thread des Aufrufers gestartet. (Entgegen den Aussagen der MSDN haben nach meinen Messungen beide Klassen eine zeitliche Abweichung von max. ±10 ms.) - Alle DelayedCall-Instanzen werden in einer statischen Liste verwaltet, so lange sie laufen. Das sollte ein mögliches vorzeitiges Einsammeln durch den Garbage Collector verhindern, was mir bislang aber noch nie aufgefallen wäre. Man kann aber auch weiterhin selbst Referenzen auf eine Instanz halten, um sie später zu steuern.
- Die Semantik der
Fire
-Methode wurde so geändert, dass ein doppelter Aufruf nahe dem geplanten Aufrufzeitpunkt verhindert wird. Um die Callback-Methode jederzeit sofort aufzurufen, sollte manReset(0)
verwenden. - Auch wenn es kein üblicher Anwendungsfall ist, sollten die statischen und Instanzmethoden der DelayedCall-Klassen threadsicher sein.
Die folgenden Einträge beziehen sich auf die alte Version der Datei:
Reset
-Methoden hinzugefügt, um für Aufrufe mit einem Parameter gleichzeitig den Parameterwert zu ändern. Außerdem wurde der Ereignisaufruf im Fall eines Abbruchs besser gegen einen verzögerten Timer-Aufruf gesichert. Das Exception-Handling wurde auskommentiert, um Ausnahmefehler durch die Anwendung bearbeiten zu lassen.
SetTimeout
, mit der vorab die Verzögerungszeit gesetzt werden kann, ohne (wie beim ähnlichen Konstruktor sonst üblich) den Timer sofort zu starten.
Reset
-Methoden zum erneuten Starten des Timers. Dadurch kann man langlebige DelayedCall-Objekte in Programmen verwenden, die man immer wieder abbrechen und erneut starten kann.
IsWaiting
), sowie die sofortige Ausführung der auszuführenden Funktion (Fire()
).
Licence and terms of use
Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. (GNU All-Permissive licence)
Statistic data
- Created on 2006-03-15, updated on 2015-02-08.
- Ca. 180 lines of code, estimated development costs: 180 - 720 €