Timer Classe

Definizione

Genera un evento dopo un intervallo specificato, con un'opzione per generare eventi ricorrenti.

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
Ereditarietà
Implementazioni

Esempio

Nell'esempio seguente viene creata un'istanza di un System.Timers.Timer oggetto che genera l'evento Timer.Elapsed ogni due secondi (2.000 millisecondi), imposta un gestore eventi per l'evento e avvia il timer. Il gestore eventi visualizza il valore della ElapsedEventArgs.SignalTime proprietà ogni volta che viene generato.

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

Commenti

Il Timer componente è un timer basato su server che genera un Elapsed evento nell'applicazione dopo che è trascorso il numero di millisecondi nella Interval proprietà. È possibile configurare l'oggetto Timer per generare l'evento una sola volta o più volte usando la AutoReset proprietà . In genere, un Timer oggetto viene dichiarato a livello di classe in modo che rimanga nell'ambito purché sia necessario. È quindi possibile gestire il relativo Elapsed evento per fornire un'elaborazione regolare. Si supponga, ad esempio, di avere un server critico che deve essere mantenuto in esecuzione 24 ore al giorno, 7 giorni alla settimana. È possibile creare un servizio che usa un Timer oggetto per controllare periodicamente il server e assicurarsi che il sistema sia operativo. Se il sistema non risponde, il servizio potrebbe tentare di riavviare il server o inviare una notifica a un amministratore.

Importante

La Timer classe non è disponibile per tutte le implementazioni e le versioni di .NET, ad esempio .NET Standard 1.6 e versioni precedenti. In questi casi, è possibile usare invece la System.Threading.Timer classe .

Il tipo implementa l'interfaccia IDisposable. Dopo aver utilizzato il tipo, è necessario eliminarlo direttamente o indirettamente. Per eliminare direttamente il tipo, chiamare il metodo Dispose in un blocco try/catch. Per eliminarlo indirettamente, utilizzare un costrutto di linguaggio come ad esempio using in C# o Using in Visual Basic. Per altre informazioni, vedere la sezione "Uso di un oggetto che implementa IDisposable" nell'argomento relativo all'interfaccia IDisposable.

La classe basata su System.Timers.Timer server è progettata per l'uso con thread di lavoro in un ambiente multithreading. I timer del server possono spostarsi tra thread per gestire l'evento generato Elapsed , con conseguente maggiore accuratezza rispetto ai timer di Windows nella generazione dell'evento in tempo.

Il System.Timers.Timer componente genera l'evento Elapsed , in base al valore (in millisecondi) della Interval proprietà . È possibile gestire questo evento per eseguire l'elaborazione necessaria. Si supponga, ad esempio, di avere un'applicazione di vendita online che invia continuamente ordini di vendita a un database. Il servizio che compila le istruzioni per la spedizione opera su un batch di ordini anziché elaborare singolarmente ogni ordine. È possibile usare un Timer per avviare l'elaborazione batch ogni 30 minuti.

Importante

La classe System.Timers.Timer ha la stessa risoluzione dell'orologio di sistema. Ciò significa che l'evento Elapsed verrà generato a un intervallo definito dalla risoluzione dell'orologio di sistema se la Interval proprietà è minore della risoluzione dell'orologio di sistema. Per altre informazioni, vedere la proprietà Interval.

Nota

L'orologio di sistema usato è lo stesso orologio usato da GetTickCount, che non è interessato dalle modifiche apportate con timeBeginPeriod e timeEndPeriod.

Quando AutoReset è impostato su false, un System.Timers.Timer oggetto genera l'evento Elapsed una sola volta, dopo che è trascorso il primo Interval . Per continuare a generare regolarmente l'evento Elapsed a intervalli definiti da Interval, impostare su AutoResettrue, ovvero il valore predefinito.

Il Timer componente rileva e elimina tutte le eccezioni generate dai gestori eventi per l'evento Elapsed . Questo comportamento è soggetto a modifiche nelle versioni future di .NET Framework. Si noti, tuttavia, che questo non è vero dei gestori eventi che vengono eseguiti in modo asincrono e includono l'operatore await (in C#) o l'operatore Await (in Visual Basic). Le eccezioni generate in questi gestori eventi vengono propagate nuovamente al thread chiamante, come illustrato nell'esempio seguente. Per altre informazioni sulle eccezioni generate nei metodi asincroni, vedere Gestione delle eccezioni.

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

Se la SynchronizingObject proprietà è null, l'evento Elapsed viene generato in un ThreadPool thread. Se l'elaborazione dell'evento Elapsed dura più a lungo di Interval, l'evento potrebbe essere generato di nuovo in un altro ThreadPool thread. In questo caso, il gestore eventi deve essere reentrant.

Nota

Il metodo di gestione degli eventi può essere eseguito in un thread contemporaneamente a un altro thread che chiama il Stop metodo o imposta la Enabled proprietà su false. Ciò potrebbe comportare la generazione dell'evento dopo l'arresto Elapsed del timer. Il codice di esempio per il Stop metodo mostra un modo per evitare questa race condition.

Anche se SynchronizingObject non nullè , Elapsed gli eventi possono verificarsi dopo che il Dispose metodo o Stop è stato chiamato o dopo che la Enabled proprietà è stata impostata su false, perché il segnale per generare l'evento viene sempre accodato per l'esecuzione Elapsed in un thread del pool di thread. Un modo per risolvere questa race condition consiste nell'impostare un flag che indica al gestore eventi per l'evento Elapsed di ignorare gli eventi successivi.

Se si utilizza la System.Timers.Timer classe con un elemento dell'interfaccia utente, ad esempio una maschera o un controllo, senza posizionare il timer su tale elemento dell'interfaccia utente, assegnare la maschera o il controllo che contiene l'oggetto Timer alla SynchronizingObject proprietà, in modo che l'evento venga sottoposto a marshalling al thread dell'interfaccia utente.

Per un elenco dei valori di proprietà predefiniti per un'istanza di Timer, vedere il Timer costruttore .

Suggerimento

.NET include quattro classi denominate Timer, ognuna delle quali offre funzionalità diverse:

  • System.Timers.Timer (questo argomento): genera un evento a intervalli regolari. La classe è destinata all'uso come componente basato su server o di servizio in un ambiente multithreading; non ha interfaccia utente e non è visibile in fase di esecuzione.
  • System.Threading.Timer: esegue un singolo metodo di callback su un thread del pool di thread a intervalli regolari. Il metodo di callback viene definito quando viene creata un'istanza del timer e non può essere modificato. Analogamente alla System.Timers.Timer classe , questa classe è destinata all'uso come componente del servizio o basato su server in un ambiente multithreading. Non ha interfaccia utente e non è visibile in fase di esecuzione.
  • System.Windows.Forms.Timer: un componente di Windows Form che genera un evento a intervalli regolari. Il componente non dispone di interfacce utente ed è progettato per l'uso in un ambiente a thread singolo.
  • System.Web.UI.Timer (solo.NET Framework): un componente ASP.NET che esegue postback di pagine Web asincrone o sincrone a intervalli regolari.

Costruttori

Timer()

Inizializza una nuova istanza della classe Timer e imposta tutte le proprietà sui rispettivi valori iniziali.

Timer(Double)

Inizializza una nuova istanza della classe Timer e imposta la proprietà Interval sul numero di millisecondi specificato.

Timer(TimeSpan)

Inizializza una nuova istanza della Timer classe , impostando la Interval proprietà sul punto specificato.

Proprietà

AutoReset

Ottiene o imposta un valore booleano che indica se Timer deve generare l'evento Elapsed una sola volta (false) o più volte (true).

CanRaiseEvents

Ottiene un valore che indica se il componente può generare un evento.

(Ereditato da Component)
Container

Ottiene l'oggetto IContainer che contiene Component.

(Ereditato da Component)
DesignMode

Ottiene un valore che indica se il Component si trova in modalità progettazione.

(Ereditato da Component)
Enabled

Ottiene o imposta un valore che indica se Timer deve generare l'evento Elapsed.

Events

Ottiene l'elenco dei gestori eventi allegati a questo Component.

(Ereditato da Component)
Interval

Ottiene o imposta l'intervallo, espresso in millisecondi, in cui generare l'evento Elapsed.

Site

Ottiene o imposta il sito che associa l'oggetto Timer al contenitore in modalità progettazione.

SynchronizingObject

Ottiene o imposta l'oggetto usato per effettuare il marshalling delle chiamate del gestore eventi generate alla scadenza di un intervallo.

Metodi

BeginInit()

Avvia l'inizializzazione in fase di esecuzione di un oggetto Timer usato in un form o da un altro componente.

Close()

Rilascia le risorse usate da Timer.

CreateObjRef(Type)

Consente di creare un oggetto che contiene tutte le informazioni rilevanti necessarie per la generazione del proxy utilizzato per effettuare la comunicazione con un oggetto remoto.

(Ereditato da MarshalByRefObject)
Dispose()

Rilascia tutte le risorse usate da Component.

(Ereditato da Component)
Dispose(Boolean)

Rilascia tutte le risorse usate dall'oggetto Timer corrente.

EndInit()

Termina l'inizializzazione in fase di esecuzione di un oggetto Timer usato in un form o da un altro componente.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetLifetimeService()
Obsoleti.

Consente di recuperare l'oggetto servizio di durata corrente per controllare i criteri di durata per l'istanza.

(Ereditato da MarshalByRefObject)
GetService(Type)

Consente di restituire un oggetto che rappresenta un servizio fornito da Component o dal relativo Container.

(Ereditato da Component)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
InitializeLifetimeService()
Obsoleti.

Ottiene un oggetto servizio di durata per controllare i criteri di durata per questa istanza.

(Ereditato da MarshalByRefObject)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
MemberwiseClone(Boolean)

Crea una copia dei riferimenti dell'oggetto MarshalByRefObject corrente.

(Ereditato da MarshalByRefObject)
Start()

Avvia la generazione dell'evento Elapsed impostando Enabled su true.

Stop()

Arresta la generazione dell'evento Elapsed impostando Enabled su false.

ToString()

Restituisce un oggetto String che contiene il nome dell'eventuale oggetto Component. Questo metodo non deve essere sottoposto a override.

(Ereditato da Component)

Eventi

Disposed

Si verifica quando il componente viene eliminato da una chiamata al metodo Dispose().

(Ereditato da Component)
Elapsed

Si verifica quando l'intervallo scade.

Si applica a

Thread safety

Tutti i membri pubblici static di questo tipo sono thread-safe. Non è invece garantita la sicurezza dei membri dell'istanza.

Vedi anche