Timer Klasse
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Generiert nach Ablauf eines festgelegten Intervalls ein Ereignis. Bietet auch die Option zum Generieren wiederkehrender Ereignisse.
public ref class Timer : System::ComponentModel::Component, System::ComponentModel::ISupportInitialize
public class Timer : System.ComponentModel.Component, System.ComponentModel.ISupportInitialize
type Timer = class
inherit Component
interface ISupportInitialize
Public Class Timer
Inherits Component
Implements ISupportInitialize
- Vererbung
- Implementiert
Beispiele
Im folgenden Beispiel wird ein System.Timers.Timer
-Objekt instanziiert, das sein Timer.Elapsed Ereignis alle zwei Sekunden (2.000 Millisekunden) auslöst, einen Ereignishandler für das Ereignis einrichtet und den Timer startet. Der Ereignishandler zeigt den Wert der ElapsedEventArgs.SignalTime-Eigenschaft bei jedem Auslösen an.
using System;
using System.Timers;
public class Example
{
private static System.Timers.Timer aTimer;
public static void Main()
{
SetTimer();
Console.WriteLine("\nPress the Enter key to exit the application...\n");
Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
Console.ReadLine();
aTimer.Stop();
aTimer.Dispose();
Console.WriteLine("Terminating the application...");
}
private static void SetTimer()
{
// Create a timer with a two second interval.
aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
e.SignalTime);
}
}
// The example displays output like the following:
// Press the Enter key to exit the application...
//
// The application started at 09:40:29.068
// The Elapsed event was raised at 09:40:31.084
// The Elapsed event was raised at 09:40:33.100
// The Elapsed event was raised at 09:40:35.100
// The Elapsed event was raised at 09:40:37.116
// The Elapsed event was raised at 09:40:39.116
// The Elapsed event was raised at 09:40:41.117
// The Elapsed event was raised at 09:40:43.132
// The Elapsed event was raised at 09:40:45.133
// The Elapsed event was raised at 09:40:47.148
//
// Terminating the application...
open System
open System.Timers
let onTimedEvent source (e: ElapsedEventArgs) =
printfn $"""The Elapsed event was raised at {e.SignalTime.ToString "HH:mm:ss.fff"}"""
// Create a timer with a two second interval.
let aTimer = new Timer 2000
// Hook up the Elapsed event for the timer.
aTimer.Elapsed.AddHandler onTimedEvent
aTimer.AutoReset <- true
aTimer.Enabled <- true
printfn "\nPress the Enter key to exit the application...\n"
printfn $"""The application started at {DateTime.Now.ToString "HH:mm:ss.fff"}"""
stdin.ReadLine() |> ignore
aTimer.Stop()
aTimer.Dispose()
printfn "Terminating the application..."
// The example displays output like the following:
// Press the Enter key to exit the application...
//
// The application started at 09:40:29.068
// The Elapsed event was raised at 09:40:31.084
// The Elapsed event was raised at 09:40:33.100
// The Elapsed event was raised at 09:40:35.100
// The Elapsed event was raised at 09:40:37.116
// The Elapsed event was raised at 09:40:39.116
// The Elapsed event was raised at 09:40:41.117
// The Elapsed event was raised at 09:40:43.132
// The Elapsed event was raised at 09:40:45.133
// The Elapsed event was raised at 09:40:47.148
//
// Terminating the application...
Imports System.Timers
Public Module Example
Private aTimer As System.Timers.Timer
Public Sub Main()
SetTimer()
Console.WriteLine("{0}Press the Enter key to exit the application...{0}",
vbCrLf)
Console.WriteLine("The application started at {0:HH:mm:ss.fff}",
DateTime.Now)
Console.ReadLine()
aTimer.Stop()
aTimer.Dispose()
Console.WriteLine("Terminating the application...")
End Sub
Private Sub SetTimer()
' Create a timer with a two second interval.
aTimer = New System.Timers.Timer(2000)
' Hook up the Elapsed event for the timer.
AddHandler aTimer.Elapsed, AddressOf OnTimedEvent
aTimer.AutoReset = True
aTimer.Enabled = True
End Sub
' The event handler for the Timer.Elapsed event.
Private Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
e.SignalTime)
End Sub
End Module
' The example displays output like the following:
' Press the Enter key to exit the application...
'
' The application started at 09:40:29.068
' The Elapsed event was raised at 09:40:31.084
' The Elapsed event was raised at 09:40:33.100
' The Elapsed event was raised at 09:40:35.100
' The Elapsed event was raised at 09:40:37.116
' The Elapsed event was raised at 09:40:39.116
' The Elapsed event was raised at 09:40:41.117
' The Elapsed event was raised at 09:40:43.132
' The Elapsed event was raised at 09:40:45.133
' The Elapsed event was raised at 09:40:47.148
'
' Terminating the application...
Hinweise
Die Timer-Komponente ist ein serverbasierter Timer, der nach Verstreichen der in der Interval-Eigenschaft angegebenen Zeit (in Millisekunden) ein Elapsed-Ereignis in Ihrer Anwendung auslöst. Sie können das Timer-Objekt mit der AutoReset-Eigenschaft so konfigurieren, dass es das Ereignis nur einmal oder wiederholt auslöst. Normalerweise wird ein Timer-Objekt so auf Klassenebene deklariert, dass es im Gültigkeitsbereich verbleibt, solange es benötigt wird. Sie können das zugehörige Elapsed-Ereignis dann behandeln, um eine zyklische Verarbeitung zu ermöglichen. Nehmen wir beispielsweise an, Sie haben einen kritischen Server, der rund um die Uhr in Betrieb gehalten werden muss. Hierfür könnten Sie einen Dienst erstellen, der den Server mithilfe eines Timer-Objekts in regelmäßigen Abständen periodisch überprüft und sicherstellt, dass das System fehlerfrei ausgeführt wird. Falls das System nicht reagiert, könnte der Dienst versuchen, den Server neu zu starten, oder einen Administrator benachrichtigen.
Wichtig
Die Timer-Klasse ist nicht für alle .NET-Implementierungen und -Versionen verfügbar, beispielsweise nicht für .NET Standard 1.6 und älter. In diesen Fällen können Sie stattdessen die System.Threading.Timer-Klasse verwenden.
Dieser Typ implementiert die IDisposable-Schnittstelle. Nach Abschluss der Verwendung sollten Sie den Typ entweder direkt oder indirekt löschen. Zum direkten Löschen des Typs rufen Sie seine Dispose-Methode in einem try
/catch
-Block auf. Zum indirekten Löschen verwenden Sie ein Sprachkonstrukt wie using
(in C#) oder Using
(in Visual Basic). Weitere Informationen finden Sie im Abschnitt „Verwenden eines Objekts, das IDisposable implementiert“ des Themas „Die IDisposable-Schnittstelle“.
Die serverbasierte System.Timers.Timer-Klasse ist für die Verwendung mit Workerthreads in einer Multithreadumgebung konzipiert. Servertimer können threadübergreifend eingesetzt werden, um das ausgelöste Elapsed-Ereignis zu behandeln. Hierdurch wird eine im Vergleich zu Windows-Timern größere Genauigkeit beim rechtzeitigen Auslösen des Ereignisses erzielt.
Die System.Timers.Timer-Komponente löst basierend auf dem Wert der Eigenschaft Interval (in Millisekunden) das Elapsed-Ereignis aus. Sie können dieses Ereignis behandeln, um die erforderliche Verarbeitung durchzuführen. Angenommen, Sie haben eine Anwendung für den Onlinevertrieb entwickelt, die fortlaufend Kundenaufträge an eine Datenbank sendet. Der Dienst, der die Versandanweisungen zusammenstellt, bearbeitet immer mehrere Aufträge gleichzeitig statt jedes Auftrags einzeln. Mit einem Timer könnten Sie die Batchverarbeitung alle 30 Minuten starten.
Wichtig
Die System.Timers.Timer-Klasse hat die gleiche Auflösung wie die Systemuhr. Das bedeutet, dass das Elapsed-Ereignis in einem durch die Auflösung der Systemuhr definierten Intervall ausgelöst wird, wenn die Interval-Eigenschaft kleiner als die Systemuhrauflösung ist. Weitere Informationen finden Sie in den Ausführungen zur Interval-Eigenschaft.
Hinweis
Bei der verwendeten Systemuhr handelt es sich um dieselbe Uhr, die von GetTickCount verwendet wird. Dies ist nicht von Änderungen betroffen, die mit timeBeginPeriod und timeEndPeriod vorgenommen werden.
Wenn AutoReset auf false
festgelegt ist, löst ein System.Timers.Timer-Objekt das Elapsed-Ereignis nach dem Verstreichen des ersten Interval nur einmalig aus. Damit das Elapsed-Ereignis regelmäßig in dem durch Interval definierten Intervall ausgelöst wird, legen Sie AutoReset auf true
fest. Dies entspricht auch dem Standardwert.
Die Timer-Komponente fängt alle Ausnahmen, die von Ereignishandlern für das Elapsed-Ereignis ausgelöst werden, ab und unterdrückt sie. Dieses Verhalten kann sich in zukünftigen .NET Framework-Versionen ändern. Beachten Sie jedoch, dass dies nicht für Ereignishandler gilt, die asynchron ausgeführt werden und den await
Operator (in C#) oder den Await
Operator (in Visual Basic) enthalten. Ausnahmen, die in diesen Ereignishandlern ausgelöst werden, werden wie im folgenden Beispiel veranschaulicht an den aufrufenden Thread übermittelt. Weitere Informationen zu Ausnahmen, die in asynchronen Methoden ausgelöst werden, finden Sie unter Ausnahmebehandlung.
using System;
using System.Threading.Tasks;
using System.Timers;
class Example
{
static void Main()
{
Timer timer = new Timer(1000);
timer.Elapsed += async ( sender, e ) => await HandleTimer();
timer.Start();
Console.Write("Press any key to exit... ");
Console.ReadKey();
}
private static Task HandleTimer()
{
Console.WriteLine("\nHandler not implemented..." );
throw new NotImplementedException();
}
}
// The example displays output like the following:
// Press any key to exit...
// Handler not implemented...
//
// Unhandled Exception: System.NotImplementedException: The method or operation is not implemented.
// at Example.HandleTimer()
// at Example.<<Main>b__0>d__2.MoveNext()
// --- End of stack trace from previous location where exception was thrown ---
// at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c__DisplayClass2.<ThrowAsync>b__5(Object state)
// at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
// at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
// at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
// at System.Threading.ThreadPoolWorkQueue.Dispatch()
open System
open System.Threading.Tasks
open System.Timers
let handleTimer () =
printfn "\nHandler not implemented..."
raise (NotImplementedException()): Task
let timer = new Timer 1000
timer.Elapsed.AddHandler(fun sender e -> task { do! handleTimer () } |> ignore)
timer.Start()
printf "Press any key to exit... "
Console.ReadKey() |> ignore
// The example displays output like the following:
// Press any key to exit...
// Handler not implemented...
//
// Unhandled Exception: System.NotImplementedException: The method or operation is not implemented.
// at Example.HandleTimer()
// at Example.<<Main>b__0>d__2.MoveNext()
// --- End of stack trace from previous location where exception was thrown ---
// at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c__DisplayClass2.<ThrowAsync>b__5(Object state)
// at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
// at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
// at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
// at System.Threading.ThreadPoolWorkQueue.Dispatch()
Imports System.Threading.Tasks
Imports System.Timers
Public Module Example
Public Sub Main()
Dim timer As New Timer(1000)
AddHandler timer.Elapsed, AddressOf Example.HandleTimer
'timer.Elapsed = Async ( sender, e ) => await HandleTimer()
timer.Start()
Console.Write("Press any key to exit... ")
Console.ReadKey()
End Sub
Private Async Sub HandleTimer(sender As Object, e As EventArgs)
Await Task.Run(Sub()
Console.WriteLine()
Console.WriteLine("Handler not implemented..." )
Throw New NotImplementedException()
End Sub)
End Sub
End Module
' The example displays output like the following:
' Press any key to exit...
' Handler not implemented...
'
' Unhandled Exception: System.NotImplementedException: The method or operation is not implemented.
' at Example._Lambda$__1()
' at System.Threading.Tasks.Task.Execute()
' --- End of stack trace from previous location where exception was thrown ---
' at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
' at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
' at Example.VB$StateMachine_0_HandleTimer.MoveNext()
' --- End of stack trace from previous location where exception was thrown ---
' at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c__DisplayClass2.<ThrowAsync>b__5(Object state)
' at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
' at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
' at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
' at System.Threading.ThreadPoolWorkQueue.Dispatch()
Wenn die SynchronizingObject-Eigenschaft null
ist, wird das Elapsed-Ereignis für einen ThreadPool-Thread ausgelöst. Dauert die Verarbeitung des Elapsed-Ereignisses länger als Interval, dann kann das Ereignis für einen anderen ThreadPool-Thread erneut ausgelöst werden. In dieser Situation muss der Ereignishandler eintrittsinvariant sein.
Hinweis
Die Ereignisbehandlungsmethode kann für einen Thread zur gleichen Zeit ausgeführt werden, zu der ein anderer Thread die Stop-Methode aufruft oder die Enabled-Eigenschaft auf false
festlegt. Dies kann dazu führen, dass das Elapsed-Ereignis ausgelöst wird, nachdem der Timer gestoppt wurde. Der Beispielcode für die Stop-Methode zeigt eine Möglichkeit, diese Racebedingung zu vermeiden.
Auch wenn SynchronizingObject nicht null
ist, können Elapsed-Ereignisse auftreten, wenn die Methoden Dispose oder Stop aufgerufen wurden oder die Enabled-Eigenschaft auf false
festgelegt wurde, da das Signal zum Auslösen des Elapsed-Ereignisses für die Ausführung stets in die Warteschlange eines Threadpoolthreads eingereiht wird. Eine Möglichkeit, diese Racebedingung aufzulösen, besteht darin, ein Flag zu setzen, das den Ereignishandler für das Elapsed-Ereignis anweist, nachfolgende Ereignisse zu ignorieren.
Wenn Sie die System.Timers.Timer-Klasse mit einem Benutzeroberflächenelement wie etwa einem Formular oder einem Steuerelement verwenden, ohne dafür den Timer festzulegen, weisen Sie der SynchronizingObject-Eigenschaft das Formular oder Steuerelement zu, das den Timer enthält, um das Ereignis auf den Benutzeroberflächenthread zu marshallen.
Eine Liste der Standardeigenschaftenwerte für eine Timer-Instanz finden Sie in den Ausführungen zum Timer-Konstruktor.
Tipp
.NET enthält vier Klassen mit dem Namen Timer
, die jeweils unterschiedliche Funktionen bieten:
- System.Timers.Timer (dieses Thema): Löst in regelmäßigen Abständen ein Ereignis aus. Die Klasse ist für den Einsatz als serverbasierte oder Dienstkomponente in einer Multithreadumgebung vorgesehen. Sie hat keine Benutzeroberfläche und ist zur Laufzeit nicht sichtbar.
- System.Threading.Timer: Führt in regelmäßigen Abständen eine einzelne Rückrufmethode für einen Threadpoolthread aus. Die Rückrufmethode wird definiert, wenn der Timer instanziiert wird, und kann nicht geändert werden. Wie die System.Timers.Timer-Klasse ist diese Klasse für den Einsatz als serverbasierte oder Dienstkomponente in einer Multithreadumgebung vorgesehen. Sie hat keine Benutzeroberfläche und ist zur Laufzeit nicht sichtbar.
- 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 (nur .NET Framework): Hierbei handelt es sich um eine ASP.NET-Komponente, die in regelmäßigen Abständen asynchrone oder synchrone Webseitenpostbacks durchführt.
Konstruktoren
Timer() |
Initialisiert eine neue Instanz der Timer-Klasse und legt alle Eigenschaften auf die Anfangswerte fest. |
Timer(Double) |
Initialisiert eine neue Instanz der Timer-Klasse, wobei die Interval-Eigenschaft auf den angegebenen Wert (in Millisekunden) festgelegt ist. |
Timer(TimeSpan) |
Initialisiert eine neue instance der Timer -Klasse, und legt die Interval -Eigenschaft auf den angegebenen Zeitraum fest. |
Eigenschaften
AutoReset |
Ruft einen booleschen Wert ab, der angibt, ob der Timer das Elapsed-Ereignis nur einmal ( |
CanRaiseEvents |
Ruft einen Wert ab, der angibt, ob die Komponente ein Ereignis auslösen kann. (Geerbt von Component) |
Container |
Ruft die IContainer ab, die in der Component enthalten ist. (Geerbt von Component) |
DesignMode |
Ruft einen Wert ab, der angibt, ob sich Component gegenwärtig im Entwurfsmodus befindet. (Geerbt von Component) |
Enabled |
Ruft einen Wert ab, der angibt, ob der Timer das Elapsed-Ereignis auslösen soll, oder legt diesen fest. |
Events |
Ruft die Liste der Ereignishandler ab, die dieser Component angefügt sind. (Geerbt von Component) |
Interval |
Ruft das Intervall in Millisekunden ab, in dem das Elapsed-Ereignis ausgelöst wird, oder legt dieses fest. |
Site |
Ruft die Site ab, die die Timer-Klasse im Entwurfsmodus an ihren Container bindet, oder legt diese fest. |
SynchronizingObject |
Ruft das Objekt ab, das zum Marshallen von Ereignishandleraufrufen verwendet wird, die nach Ablauf eines Intervalls ausgegeben werden, oder legt dieses fest. |
Methoden
BeginInit() |
Beginnt die Laufzeitinitialisierung eines Timer, der in einem Formular oder von einer anderen Komponente verwendet wird. |
Close() |
Gibt die von der Timer verwendeten Ressourcen frei. |
CreateObjRef(Type) |
Erstellt ein Objekt mit allen relevanten Informationen, die zum Generieren eines Proxys für die Kommunikation mit einem Remoteobjekt erforderlich sind. (Geerbt von MarshalByRefObject) |
Dispose() |
Gibt alle vom Component verwendeten Ressourcen frei. (Geerbt von Component) |
Dispose(Boolean) |
Gibt alle von der aktuellen Timer-Klasse verwendeten Ressourcen frei. |
EndInit() |
Beendet die Laufzeitinitialisierung eines Timer, der in einem Formular oder von einer anderen Komponente verwendet wird. |
Equals(Object) |
Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist. (Geerbt von Object) |
GetHashCode() |
Fungiert als Standardhashfunktion. (Geerbt von Object) |
GetLifetimeService() |
Veraltet.
Ruft das aktuelle Lebensdauerdienstobjekt ab, das die Lebensdauerrichtlinien für diese Instanz steuert. (Geerbt von MarshalByRefObject) |
GetService(Type) |
Gibt ein Objekt zurück, das einen von der Component oder von deren Container bereitgestellten Dienst darstellt. (Geerbt von Component) |
GetType() |
Ruft den Type der aktuellen Instanz ab. (Geerbt von Object) |
InitializeLifetimeService() |
Veraltet.
Ruft ein Lebensdauerdienstobjekt zur Steuerung der Lebensdauerrichtlinie für diese Instanz ab. (Geerbt von MarshalByRefObject) |
MemberwiseClone() |
Erstellt eine flache Kopie des aktuellen Object. (Geerbt von Object) |
MemberwiseClone(Boolean) |
Erstellt eine flache Kopie des aktuellen MarshalByRefObject-Objekts. (Geerbt von MarshalByRefObject) |
Start() |
Beginnt mit dem Auslösen des Elapsed-Ereignisses durch Festlegen von Enabled auf |
Stop() |
Unterbricht das Auslösen des Elapsed-Ereignisses durch Festlegen von Enabled auf |
ToString() |
Gibt einen String zurück, der den Namen der Component enthält (sofern vorhanden). Diese Methode darf nicht überschrieben werden. (Geerbt von Component) |
Ereignisse
Disposed |
Tritt auf, wenn die Komponente von einem Aufruf der Dispose()-Methode verworfen wird. (Geerbt von Component) |
Elapsed |
Tritt ein, wenn das Intervall abläuft. |
Gilt für:
Threadsicherheit
Alle öffentlichen static
-Member dieses Typs sind threadsicher. Bei Instanzmembern ist die Threadsicherheit nicht gewährleistet.