Freigeben über


Timer

.NET stellt drei Timer zur Verfügung, die in einer Multithreadumgebung verwendet werden können:

Hinweis

Einige .NET-Implementierungen können zusätzliche Timer enthalten:

  • System.Windows.Forms.Timer: eine Windows Forms-Komponente, die in regelmäßigen Abständen ein Ereignis auslöst. Die Komponente besitzt keine Benutzeroberfläche und wurde für die Verwendung in einer Singlethreadumgebung entwickelt.
  • System.Web.UI.Timer: eine ASP.NET-Komponente, die asynchrone oder synchrone Webseitenpostbacks in regelmäßigen Intervallen ausführt.
  • System.Windows.Threading.DispatcherTimer: ein Timer, der in die Dispatcher-Warteschlange integriert ist. Diese wird in einem festgelegten Zeitintervall und mit einer festgelegten Priorität verarbeitet.

Die System.Threading.Timer-Klasse

Mithilfe der System.Threading.Timer-Klasse können Sie einen Delegaten kontinuierlich in bestimmten Zeitintervallen aufrufen. Sie können diese Klasse auch verwenden, um einen einzelnen Aufruf eines Delegaten in einem bestimmten Zeitintervall zu planen. Der Delegat wird in einem ThreadPool-Thread ausgeführt.

Wenn Sie ein System.Threading.Timer-Objekt erstellen, geben Sie einen TimerCallback-Delegaten an, der die Callbackmethode definiert, ein optionales Zustandsobjekt, das an die Callbackmethode übergeben wird, die Verzögerung vor dem ersten Aufruf der Callbackmethode und das Zeitintervall zwischen den Aufrufen der Callbackmethode. Wenn Sie einen anstehenden Timer löschen möchten, rufen Sie die Timer.Dispose-Methode auf.

Im folgenden Beispiel wird ein Timer erstellt, der den bereitgestellten Delegaten zum ersten Mal nach einer Sekunde (1000 Millisekunden) und dann alle zwei Sekunden aufruft. Das Zustandsobjekt im Beispiel wird verwendet, um die Häufigkeit der Aufrufe des Delegaten zu zählen. Der Timer wird beendet, wenn der Delegat mindestens zehnmal aufgerufen wurde.

using namespace System;
using namespace System::Threading;

ref class TimerState
{
public:
    int counter;
};

ref class Example
{
private:
    static Timer^ timer;

public:
    static void TimerTask(Object^ state)
    {
        Console::WriteLine("{0:HH:mm:ss.fff}: starting a new callback.", DateTime::Now);

        TimerState^ timerState = dynamic_cast<TimerState^>(state);
        Interlocked::Increment(timerState->counter);
    }

    static void Main()
    {
        TimerCallback^ tcb = gcnew TimerCallback(&TimerTask);
        TimerState^ state = gcnew TimerState();
        state->counter = 0;
        timer = gcnew Timer(tcb, state, 1000, 2000);

        while (state->counter <= 10)
        {
            Thread::Sleep(1000);
        }

        timer->~Timer();
        Console::WriteLine("{0:HH:mm:ss.fff}: done.", DateTime::Now);
    }
};

int main()
{
    Example::Main();
}
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static Timer timer;

    static void Main(string[] args)
    {
        var timerState = new TimerState { Counter = 0 };

        timer = new Timer(
            callback: new TimerCallback(TimerTask),
            state: timerState,
            dueTime: 1000,
            period: 2000);

        while (timerState.Counter <= 10)
        {
            Task.Delay(1000).Wait();
        }

        timer.Dispose();
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
    }

    private static void TimerTask(object timerState)
    {
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
        var state = timerState as TimerState;
        Interlocked.Increment(ref state.Counter);
    }

    class TimerState
    {
        public int Counter;
    }
}
Imports System.Threading

Module Program

    Private Timer As Timer

    Sub Main(args As String())

        Dim StateObj As New TimerState
        StateObj.Counter = 0

        Timer = New Timer(New TimerCallback(AddressOf TimerTask), StateObj, 1000, 2000)

        While StateObj.Counter <= 10
            Task.Delay(1000).Wait()
        End While

        Timer.Dispose()
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.")
    End Sub

    Private Sub TimerTask(ByVal StateObj As Object)

        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.")

        Dim State As TimerState = CType(StateObj, TimerState)
        Interlocked.Increment(State.Counter)
    End Sub

    Private Class TimerState
        Public Counter As Integer
    End Class
End Module

Weitere Informationen und Beispiele finden Sie unter System.Threading.Timer.

Die System.Timers.Timer-Klasse

Ein weiterer Timer, der in einer Multithreadumgebung verwendet werden kann, ist System.Timers.Timer. Dieser löst standardmäßig ein Ereignis in einem ThreadPool-Thread aus.

Wenn Sie ein System.Timers.Timer-Objekt erstellen, können Sie das Zeitintervall angeben, in dem ein Elapsed-Ereignis ausgelöst werden soll. Verwenden Sie die Enabled-Eigenschaft, um anzugeben, ob ein Timer ein Elapsed-Ereignis auslösen soll. Wenn ein Elapsed-Event nur ausgelöst werden soll, nachdem das angegebene Intervall verstrichen ist, legen Sie AutoReset auf false fest. Der Standardwert der AutoReset-Eigenschaft ist true. Das bedeutet, dass ein Elapsed-Ereignis regelmäßig in dem von der Interval-Eigenschaft angegebenen Intervall ausgelöst wird.

Weitere Informationen und Beispiele finden Sie unter System.Timers.Timer.

System.Threading.PeriodicTimer-Klasse

Mit der System.Threading.PeriodicTimer-Klasse können Sie auf einzelne Takte eines angegebenen Intervalls warten und nach dem Aufrufen von PeriodicTimer.WaitForNextTickAsyncArbeiten ausführen.

Wenn Sie ein System.Threading.PeriodicTimer-Objekt erstellen, geben Sie einen TimeSpan-Wert an, der die Dauer zwischen den einzelnen Takten des Timers bestimmt. Anstatt wie in den vorherigen Timer-Klassen einen Rückruf zu übergeben oder einen Ereignishandler festzulegen, führen Sie die Arbeit direkt im Bereich aus und warten darauf, dass WaitForNextTickAsync den Timer um das angegebene Intervall verlängert.

Die WaitForNextTickAsync-Methode gibt nach erfolgreichem Auslösen des Timers ValueTask<bool>true zurück. Wenn der Timer durch Aufrufen von PeriodicTimer.Dispose abgebrochen wurde, gibt sie false zurück. WaitForNextTickAsync akzeptiert optional ein CancellationToken, was zu einer TaskCanceledException führt, wenn ein Abbruch angefordert wurde.

Weitere Informationen finden Sie unter System.Threading.PeriodicTimer.

Siehe auch