Timer

.NET fornisce tre timer da usare in un ambiente con multithreading:

Nota

Alcune implementazioni .NET possono includere altri timer:

  • 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: un componente ASP.NET che esegue postback asincroni o sincroni di pagina Web in base a intervalli regolari.
  • System.Windows.Threading.DispatcherTimer: un timer integrato nella coda del Dispatcher che viene elaborata in un intervallo di tempo specifico e con una priorità specifica.

Classe System.Threading.Timer

La classe System.Threading.Timer consente di chiamare in modo continuativo un delegato a determinati intervalli di tempo. È inoltre possibile usare questa classe per pianificare una singola chiamata a un delegato in un intervallo di tempo specifico. Il delegato viene eseguito su un thread ThreadPool.

Quando si crea un oggetto System.Threading.Timer, si specifica un delegato TimerCallback che definisce il metodo di callback, un oggetto di stato facoltativo passato al callback, il tempo di attesa prima della prima chiamata di callback e l'intervallo di tempo tra le chiamate di callback. Per annullare un timer in sospeso, chiamare il metodo Timer.Dispose.

L'esempio seguente illustra come creare un timer che chiama il delegato fornito per la prima volta dopo un secondo (1000 millisecondi) e quindi ogni due secondi. L'oggetto di stato nell'esempio viene usato per contare quante volte viene chiamato il delegato. Il timer viene arrestato dopo aver chiamato il delegato almeno 10 volte.

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

Per altre informazioni ed esempi, vedere System.Threading.Timer.

Classe System.Timers.Timer

Un altro timer utilizzabile in un ambiente con multithreading è System.Timers.Timer, che per impostazione predefinita genera un evento in un thread ThreadPool.

Quando si crea un oggetto System.Timers.Timer, è possibile specificare l'intervallo di tempo in cui si desidera generare un evento Elapsed. Usare la proprietà Enabled per indicare se un timer deve generare un evento Elapsed. Se un evento Elapsed deve essere generato una sola volta dopo l'intervallo specificato, impostare AutoReset su false. Il valore predefinito della proprietà AutoReset è true, vale a dire che un evento Elapsed viene generato periodicamente in base all'intervallo definito dalla proprietà Interval.

Per altre informazioni ed esempi, vedere System.Timers.Timer.

Classe System.Threading.PeriodicTimer

La classe System.Threading.PeriodicTimer consente di attendere i singoli tick di un intervallo specificato, eseguendo il lavoro dopo aver chiamato PeriodicTimer.WaitForNextTickAsync.

Quando si crea un oggetto System.Threading.PeriodicTimer, si specifica un TimeSpan che determina l'intervallo di tempo tra ogni tick del timer. Anziché passare un callback o impostare un gestore eventi come nelle classi timer precedenti, è possibile eseguire operazioni direttamente nell'ambito, in attesa che WaitForNextTickAsync faccia avanzare il timer in base all'intervallo specificato.

Il metodo WaitForNextTickAsync restituisce un ValueTask<bool>; true al completamento dell'attivazione del timer e false quando il timer è stato annullato chiamando PeriodicTimer.Dispose. WaitForNextTickAsync facoltativamente accetta un CancellationToken, che comporta un TaskCanceledException quando è stato richiesto un annullamento.

Per ulteriori informazioni, vedere System.Threading.PeriodicTimer.

Vedi anche