Udostępnij za pośrednictwem


Timer Klasa

Definicja

Generuje zdarzenie po ustawionym interwale z opcją generowania zdarzeń cyklicznych.

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
Dziedziczenie
Implementuje

Przykłady

Poniższy przykład tworzy wystąpienie System.Timers.Timer obiektu, który uruchamia zdarzenie Timer.Elapsed co dwie sekundy (2000 milisekund), konfiguruje procedurę obsługi zdarzeń dla zdarzenia i uruchamia czasomierz. Program obsługi zdarzeń wyświetla wartość ElapsedEventArgs.SignalTime właściwości za każdym razem, gdy jest wywoływana.

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...

Uwagi

Składnik Timer jest czasomierzem opartym na serwerze, który zgłasza Elapsed zdarzenie w aplikacji po upływie Interval liczby milisekund we właściwości. Obiekt można skonfigurować Timer tak, aby zgłaszał zdarzenie tylko raz lub wielokrotnie przy użyciu AutoReset właściwości . Zazwyczaj obiekt jest deklarowany na poziomie klasy, Timer tak aby pozostał w zakresie tak długo, jak jest to potrzebne. Następnie można obsłużyć jego Elapsed zdarzenie w celu zapewnienia regularnego przetwarzania. Załóżmy na przykład, że masz krytyczny serwer, który musi być uruchomiony 24 godziny dziennie, 7 dni w tygodniu. Można utworzyć usługę, która używa Timer obiektu, aby okresowo sprawdzać serwer i upewnić się, że system jest uruchomiony. Jeśli system nie odpowiada, usługa może podjąć próbę ponownego uruchomienia serwera lub powiadomić administratora.

Ważna

Klasa Timer nie jest dostępna dla wszystkich implementacji i wersji platformy .NET, takich jak .NET Standard 1.6 i starsze wersje. W takich przypadkach można użyć System.Threading.Timer klasy .

Ten typ implementuje interfejs IDisposable. Po zakończeniu korzystania z typu danych, należy go usunąć w sposób bezpośredni lub pośredni. Aby usunąć typ bezpośrednio, wywołaj metodę Dispose w bloku try/catch. Aby usunąć go pośrednio, należy użyć konstrukcji języka, takiej jak using (w języku C#) lub Using (w Visual Basic). Aby uzyskać więcej informacji, zobacz sekcję "Używanie obiektu implementującego IDisposable" (Using an Object that Implements IDisposable) w temacie interfejsu IDisposable.

Klasa oparta na System.Timers.Timer serwerze jest przeznaczona do użytku z wątkami roboczymi w środowisku wielowątkowym. Czasomierze serwera mogą przenosić się między wątkami w celu obsługi zgłoszonego Elapsed zdarzenia, co powoduje większą dokładność niż czasomierze systemu Windows podczas podnoszenia zdarzenia na czas.

Składnik System.Timers.Timer zgłasza Elapsed zdarzenie na podstawie wartości (w milisekundach) Interval właściwości . To zdarzenie można obsłużyć w celu wykonania potrzebnego przetwarzania. Załóżmy na przykład, że masz aplikację sprzedaży online, która stale publikuje zamówienia sprzedaży w bazie danych. Usługa, która kompiluje instrukcje dotyczące wysyłki, działa na partii zamówień, a nie przetwarzania poszczególnych zamówień osobno. Można użyć elementu , Timer aby rozpocząć przetwarzanie wsadowe co 30 minut.

Ważna

Klasa System.Timers.Timer ma taką samą rozdzielczość jak zegar systemowy. Oznacza to, że Elapsed zdarzenie zostanie wyzwolony w interwale zdefiniowanym przez rozdzielczość zegara systemowego, jeśli Interval właściwość jest mniejsza niż rozdzielczość zegara systemowego. Aby uzyskać więcej informacji, zobacz właściwość Interval.

Uwaga / Notatka

Zegar systemowy, który jest używany jest ten sam zegar używany przez GetTickCount, który nie ma wpływu na zmiany wprowadzone w timeBeginPeriod i timeEndPeriod.

Gdy AutoReset jest ustawiona wartość false, System.Timers.Timer obiekt zgłasza Elapsed zdarzenie tylko raz, po upływie pierwszego Interval . Aby regularnie podnosić Elapsed zdarzenie w interwale zdefiniowanym przez Intervalparametr , ustaw AutoReset wartość true, która jest wartością domyślną.

Składnik Timer przechwytuje i pomija wszystkie wyjątki zgłaszane przez programy obsługi zdarzeń dla Elapsed zdarzenia. To zachowanie może ulec zmianie w przyszłych wersjach programu .NET Framework. Należy jednak pamiętać, że nie dotyczy to procedur obsługi zdarzeń wykonywanych asynchronicznie i dołączania await operatora (w języku C#) lub Await operatora (w Visual Basic). Wyjątki zgłoszone w tych programach obsługi zdarzeń są propagowane z powrotem do wątku wywołującego, jak pokazano w poniższym przykładzie. Aby uzyskać więcej informacji na temat wyjątków zgłaszanych w metodach asynchronicznych, zobacz Obsługa wyjątków.

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()

SynchronizingObject Jeśli właściwość to null, Elapsed zdarzenie jest zgłaszane w wątkuThreadPool. Jeśli przetwarzanie Elapsed zdarzenia trwa dłużej niż Interval, zdarzenie może zostać zgłoszone ponownie w innym ThreadPool wątku. W takiej sytuacji procedura obsługi zdarzeń powinna być ponownie dostępna.

Uwaga / Notatka

Metoda obsługi zdarzeń może być uruchamiana w jednym wątku w tym samym czasie, gdy inny wątek wywołuje Stop metodę lub ustawia Enabled właściwość na false. Może to spowodować Elapsed wywołanie zdarzenia po zatrzymaniu czasomierza. Przykładowy kod Stop metody przedstawia jeden ze sposobów uniknięcia tego stanu wyścigu.

Nawet jeśli SynchronizingObject nie nullma wartości , Elapsed zdarzenia mogą wystąpić po Dispose wywołaniu metody lub Stop lub po Enabled ustawieniu właściwości na falsewartość , ponieważ sygnał do podniesienia Elapsed zdarzenia jest zawsze w kolejce do wykonania w wątku puli wątków. Jednym ze sposobów rozwiązania tego stanu wyścigu jest ustawienie flagi, która nakazuje programowi obsługi zdarzeń ignorowanie Elapsed kolejnych zdarzeń.

Jeśli używasz System.Timers.Timer klasy z elementem interfejsu użytkownika, takim jak formularz lub kontrolka, bez umieszczania czasomierza na tym elemecie interfejsu użytkownika, przypisz formularz lub kontrolkę zawierającą Timer element do SynchronizingObject właściwości, aby zdarzenie było marshalowane do wątku interfejsu użytkownika.

Aby uzyskać listę domyślnych wartości właściwości dla wystąpienia Timerprogramu , zobacz Timer konstruktor.

Wskazówka

Platforma .NET zawiera cztery klasy o nazwie Timer, z których każda oferuje różne funkcje:

  • System.Timers.Timer (ten temat): uruchamia zdarzenie w regularnych odstępach czasu. Klasa jest przeznaczona do użycia jako składnik usługi lub oparty na serwerze w środowisku wielowątkowym; nie ma interfejsu użytkownika i nie jest widoczny w czasie wykonywania.
  • System.Threading.Timer: wykonuje pojedynczą metodę wywołania zwrotnego w wątku puli wątków w regularnych odstępach czasu. Metoda wywołania zwrotnego jest definiowana po utworzeniu wystąpienia czasomierza i nie można jej zmienić. System.Timers.Timer Podobnie jak klasa, ta klasa jest przeznaczona do użycia jako składnik usługi lub oparty na serwerze w środowisku wielowątkowym; nie ma interfejsu użytkownika i nie jest widoczna w czasie wykonywania.
  • System.Windows.Forms.Timer: składnik Windows Forms, który uruchamia zdarzenie w regularnych odstępach czasu. Składnik nie ma interfejsu użytkownika i jest przeznaczony do użytku w środowisku jednowątkowym.
  • System.Web.UI.Timer (Tylko.NET Framework): składnik ASP.NET, który wykonuje asynchroniczne lub synchroniczne ogłaszanie zwrotne stron internetowych w regularnym odstępie czasu.

Konstruktory

Nazwa Opis
Timer()

Inicjuje Timer nowe wystąpienie klasy i ustawia wszystkie właściwości na ich początkowe wartości.

Timer(Double)

Inicjuje Timer nowe wystąpienie klasy i ustawia Interval właściwość na określoną liczbę milisekund.

Timer(TimeSpan)

Inicjuje Timer nowe wystąpienie klasy, ustawiając Interval właściwość na określony okres.

Właściwości

Nazwa Opis
AutoReset

Pobiera lub ustawia wartość logiczną wskazującą, czy Timer zdarzenie powinno być wywoływane Elapsed tylko raz (false) lub wielokrotnie (true).

CanRaiseEvents

Pobiera wartość wskazującą, czy składnik może zgłosić zdarzenie.

(Odziedziczone po Component)
Container

Pobiera element IContainer zawierający element Component.

(Odziedziczone po Component)
DesignMode

Pobiera wartość wskazującą, czy Component element jest obecnie w trybie projektowania.

(Odziedziczone po Component)
Enabled

Pobiera lub ustawia wartość wskazującą, czy Timer zdarzenie powinno zostać wywołane Elapsed .

Events

Pobiera listę programów obsługi zdarzeń dołączonych do tego elementu Component.

(Odziedziczone po Component)
Interval

Pobiera lub ustawia interwał wyrażony w milisekundach, w których ma być zgłoszone Elapsed zdarzenie.

Site

Pobiera lub ustawia lokację powiązaną z Timer kontenerem w trybie projektowania.

SynchronizingObject

Pobiera lub ustawia obiekt używany do marshalingu wywołań obsługi zdarzeń, które są wystawiane po upływie interwału.

Metody

Nazwa Opis
BeginInit()

Rozpoczyna inicjowanie Timer obiektu w czasie wykonywania używanego w formularzu lub przez inny składnik.

Close()

Zwalnia zasoby używane przez program Timer.

CreateObjRef(Type)

Tworzy obiekt zawierający wszystkie istotne informacje wymagane do wygenerowania serwera proxy używanego do komunikowania się z obiektem zdalnym.

(Odziedziczone po MarshalByRefObject)
Dispose()

Zwalnia wszystkie zasoby używane przez program Component.

(Odziedziczone po Component)
Dispose(Boolean)

Zwalnia wszystkie zasoby używane przez bieżący Timerelement .

EndInit()

Kończy inicjowanie Timer obiektu w czasie wykonywania używanego w formularzu lub przez inny składnik.

Equals(Object)

Określa, czy określony obiekt jest równy bieżącemu obiektowi.

(Odziedziczone po Object)
GetHashCode()

Służy jako domyślna funkcja skrótu.

(Odziedziczone po Object)
GetLifetimeService()
Przestarzałe.

Pobiera bieżący obiekt usługi okresu istnienia, który kontroluje zasady okresu istnienia dla tego wystąpienia.

(Odziedziczone po MarshalByRefObject)
GetService(Type)

Zwraca obiekt reprezentujący usługę dostarczaną przez Component obiekt lub przez obiekt Container.

(Odziedziczone po Component)
GetType()

Pobiera Type bieżącego wystąpienia.

(Odziedziczone po Object)
InitializeLifetimeService()
Przestarzałe.

Uzyskuje obiekt usługi okresu istnienia w celu kontrolowania zasad okresu istnienia dla tego wystąpienia.

(Odziedziczone po MarshalByRefObject)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Object.

(Odziedziczone po Object)
MemberwiseClone(Boolean)

Tworzy płytkią kopię bieżącego MarshalByRefObject obiektu.

(Odziedziczone po MarshalByRefObject)
Start()

Rozpoczyna podnoszenie Elapsed zdarzenia, ustawiając wartość Enabled .true

Stop()

Zatrzymuje podnoszenie Elapsed zdarzenia, ustawiając wartość Enabled .false

ToString()

Zwraca wartość zawierającą String nazwę Component, jeśli istnieje. Ta metoda nie powinna być zastępowana.

(Odziedziczone po Component)

Zdarzenia

Nazwa Opis
Disposed

Występuje, gdy składnik jest usuwany przez wywołanie Dispose() metody .

(Odziedziczone po Component)
Elapsed

Występuje, gdy interwał upłynie.

Dotyczy

Bezpieczeństwo wątkowe

Wszyscy publiczni static członkowie tego typu są bezpieczni wątkami. Członkowie instancji nie mają gwarancji bezpieczeństwa wątkowego.

Zobacz też