HOWTO · Csharp

Wie man einen Verzögerungstimer in C# erstellt

Dieser Artikel führt ein, wie man einen Verzögerungstimer in C# erstellt. Er enthält vier verschiedene Methoden: Thread.Sleep(), Task.Delay(), System.Timers.Timer und System.Threading.Timer.

Auf dieser Seite

Um in C# eine Verzögerung hinzuzufügen, wählen Sie Thread.Sleep(), um den aktuellen Thread zu blockieren, Task.Delay(), um asynchron zu warten, oder eine Timer-Klasse, um einen Callback zu planen. Die folgenden Beispiele verwenden ein Intervall von zwei Sekunden und zeigen, wie sich jede Option verhält. Sie wurden in der bereitgestellten Laufzeitumgebung nicht ausgeführt, daher wird keine beobachtete Ausgabe behauptet.

Verwenden der Thread.Sleep()-Methode, um eine Verzögerung in C# zu erstellen

Thread.Sleep() hält den aktuellen Thread für die angegebene Anzahl von Millisekunden an. Da dieser Thread während der Wartezeit keine andere Arbeit erledigen kann, sollten Sie diesen Ansatz nur verwenden, wenn das Blockieren angemessen ist, etwa in einem kurzen synchronen Konsolenprogramm.

Dieses vollständige Beispiel gibt eine Nachricht aus, wartet zwei Sekunden und gibt dann eine weitere Nachricht aus:

using System;
using System.Threading;

class DelayExample
{
    static void Main()
    {
        Console.WriteLine("The delay starts.");
        Thread.Sleep(2000);
        Console.WriteLine("The delay ends.");
    }
}

Das Argument ist in Millisekunden angegeben, 2000 fordert also eine Wartezeit von zwei Sekunden an. Die tatsächlich verstrichene Zeit kann je nach Systemplanung variieren.

Verwenden der Task.Delay()-Methode, um eine Verzögerung in C# zu erstellen

Task.Delay() erstellt eine Aufgabe, die nach dem angeforderten Intervall abgeschlossen wird. Wenn Sie sie in einer asynchronen Methode mit await erwarten, kann diese Methode während des Wartens nachgeben, anders als bei Thread.Sleep(), das den aktuellen Thread belegt. Rufen Sie die asynchrone Methode aus dem bestehenden asynchronen Ablauf Ihrer Anwendung auf.

Dieses vollständige Beispiel behält das asynchrone Warten in einer separaten Methode und verwendet einen synchronen Einstiegspunkt, um sie aufzurufen:

using System;
using System.Threading.Tasks;

class DelayExample
{
    static void Main()
    {
        RunAsync().GetAwaiter().GetResult();
    }

    static async Task RunAsync()
    {
        Console.WriteLine("Before the delay");
        await Task.Delay(2000);
        Console.WriteLine("After the delay");
    }
}

Der await-Ausdruck setzt RunAsync fort, nachdem die Verzögerungsaufgabe abgeschlossen ist. Warten Sie in einer Anwendung, die bereits asynchrone Methoden verwendet, direkt mit await auf Task.Delay(2000), anstatt den Einstiegspunkt zu blockieren, um auf die Aufgabe zu warten.

Verwenden der System.Timers.Timer-Klasse, um eine Verzögerung in C# zu erstellen

System.Timers.Timer löst nach seinem Interval in Millisekunden ein Elapsed-Ereignis aus. Setzen Sie AutoReset für ein einzelnes Ereignis auf false; setzen Sie es auf true, wenn sich das Ereignis im Intervall wiederholen soll. Der Callback ist ereignisgesteuert, sodass das Starten eines Timers die nächste Codezeile nicht anhält.

Dieses vollständige Beispiel wartet auf das einmalige Ereignis, bevor das Konsolenprogramm beendet wird:

using System;
using System.Threading;
using System.Timers;

class DelayExample
{
    static void Main()
    {
        using (var completed = new ManualResetEvent(false))
        using (var timer = new System.Timers.Timer(2000))
        {
            timer.AutoReset = false;
            timer.Elapsed += (sender, args) =>
            {
                Console.WriteLine("Timer elapsed.");
                completed.Set();
            };

            Console.WriteLine("Timer started.");
            timer.Start();
            completed.WaitOne();
        }
    }
}

WaitOne() hält dieses Konsolenbeispiel am Leben, bis der Ereignishandler den Abschluss signalisiert. Halten Sie in einer länger laufenden Anwendung die Anwendung entsprechend ihrer normalen Ereignisschleife oder Dienstdauer am Leben, anstatt ausschließlich für den Timer eine blockierende Wartezeit hinzuzufügen.

Verwenden der System.Threading.Timer-Klasse, um eine Verzögerung in C# zu erstellen

System.Threading.Timer plant einen Callback mit einer anfänglichen Fälligkeitszeit und einer Periode. Beide Werte sind in Millisekunden angegeben. Verwenden Sie Timeout.Infinite für die Periode, wenn der Callback einmal ausgeführt werden soll; geben Sie eine endliche Periode an, um wiederholte Callbacks zu planen. Der Callback läuft getrennt von dem Code, der den Timer startet.

Dieses vollständige Beispiel plant einen Callback nach zwei Sekunden und wartet darauf, bevor es beendet wird:

using System;
using System.Threading;

class DelayExample
{
    static void Main()
    {
        using (var completed = new ManualResetEvent(false))
        using (var timer = new System.Threading.Timer(
            state =>
            {
                Console.WriteLine("Timer callback.");
                completed.Set();
            },
            null,
            2000,
            Timeout.Infinite))
        {
            Console.WriteLine("Timer scheduled.");
            completed.WaitOne();
        }
    }
}

Die Fälligkeitszeit plant den ersten Callback zwei Sekunden nach der Konstruktion. Timeout.Infinite verhindert, dass ein weiterer Callback geplant wird. Die Wartezeit hält dieses Konsolenbeispiel lange genug am Leben, um den Callback zu empfangen; eine Anwendung mit eigener Ereignisschleife kann stattdessen diese Lebensdauer verwenden.

Fazit

Verwenden Sie Thread.Sleep() für eine einfache synchrone Pause, wenn das Blockieren des aktuellen Threads akzeptabel ist. Bevorzugen Sie Task.Delay() mit await in asynchronem Code, damit die Methode während des Wartens nachgeben kann. Wählen Sie System.Timers.Timer oder System.Threading.Timer, wenn Sie eine callbackbasierte Planung benötigen, wobei AutoReset oder die Timer-Periode die Wiederholung steuert. Timer-Callbacks planen Arbeit; sie halten die sequenzielle Ausführung nicht an, und ihr Timing ist keine exakte Wanduhr-Garantie.