Dela via


Timers

.NET tillhandahåller tre timers som ska användas i en flertrådad miljö:

Kommentar

Vissa .NET-implementeringar kan innehålla ytterligare timers:

  • System.Windows.Forms.Timer: en Windows Forms-komponent som utlöser en händelse med jämna mellanrum. Komponenten har inget användargränssnitt och är utformad för användning i en entrådad miljö.
  • System.Web.UI.Timer: en ASP.NET komponent som utför asynkrona eller synkrona sidinlägg med jämna mellanrum.
  • System.Windows.Threading.DispatcherTimer: en timer som är integrerad i Dispatcher kön som bearbetas med ett angivet tidsintervall och med en angiven prioritet.

Klassen System.Threading.Timer

Med System.Threading.Timer klassen kan du kontinuerligt anropa ett ombud vid angivna tidsintervall. Du kan också använda den här klassen för att schemalägga ett enskilt anrop till ett ombud inom ett angivet tidsintervall. Ombudet körs i en ThreadPool tråd.

När du skapar ett System.Threading.Timer objekt anger du ett TimerCallback ombud som definierar motringningsmetoden, ett valfritt tillståndsobjekt som skickas till motringningen, hur lång tid det tar innan återanropet första gången och tidsintervallet mellan återanrop. Om du vill avbryta en väntande timer anropar du Timer.Dispose metoden.

I följande exempel skapas en timer som anropar det angivna ombudet för första gången efter en sekund (1 000 millisekunder) och sedan anropar den varannan sekund. Tillståndsobjektet i exemplet används för att räkna hur många gånger ombudet anropas. Timern stoppas när ombudet har anropats minst 10 gånger.

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

Mer information och exempel finns i System.Threading.Timer.

Klassen System.Timers.Timer

En annan timer som kan användas i en miljö med flera flöden är System.Timers.Timer att som standard genererar en händelse i en ThreadPool tråd.

När du skapar ett System.Timers.Timer objekt kan du ange tidsintervallet för att skapa en Elapsed händelse. Använd egenskapen Enabled för att ange om en timer ska generera en Elapsed händelse. Om du bara vill att en Elapsed händelse ska aktiveras en gång efter att det angivna intervallet har förflutit anger du AutoReset till false. Standardvärdet för AutoReset egenskapen är true, vilket innebär att en Elapsed händelse utlöses regelbundet med det intervall som definieras av Interval egenskapen.

Mer information och exempel finns i System.Timers.Timer.

Klassen System.Threading.PeriodicTimer

Med System.Threading.PeriodicTimer klassen kan du invänta enskilda tick i ett angivet intervall och utföra arbete efter att ha anropat PeriodicTimer.WaitForNextTickAsync.

När du skapar ett System.Threading.PeriodicTimer objekt anger du en TimeSpan som avgör hur lång tid det tar mellan varje tick i timern. I stället för att skicka ett återanrop eller ställa in en händelsehanterare som i föregående timerklasser utför du arbete direkt i omfånget i väntan på WaitForNextTickAsync att föra timern framåt med det angivna intervallet.

Metoden WaitForNextTickAsync returnerar en ValueTask<bool>; true vid lyckad utskjutning av timern och false när timern har avbrutits genom att anropa PeriodicTimer.Dispose. WaitForNextTickAsync om du vill kan du acceptera en CancellationToken, vilket resulterar i en TaskCanceledException när en annullering har begärts.

Mer information finns i System.Threading.PeriodicTimer.

Se även