Czasomierze

Platforma .NET udostępnia trzy czasomierze do użycia w środowisku wielowątkowym:

Uwaga

Niektóre implementacje platformy .NET mogą obejmować dodatkowe czasomierze:

  • 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: składnik ASP.NET, który wykonuje asynchroniczne lub synchroniczne ogłaszanie zwrotne stron internetowych w regularnych odstępach czasu.
  • System.Windows.Threading.DispatcherTimer: czasomierz zintegrowany z kolejką Dispatcher , który jest przetwarzany w określonym przedziale czasu i o określonym priorytetzie.

Klasa System.Threading.Timer

Klasa System.Threading.Timer umożliwia ciągłe wywoływanie delegata w określonych interwałach czasu. Tej klasy można również użyć do zaplanowania pojedynczego wywołania delegata w określonym przedziale czasu. Delegat jest wykonywany w wątku ThreadPool .

Podczas tworzenia System.Threading.Timer obiektu należy określić TimerCallback delegata definiującego metodę wywołania zwrotnego, opcjonalny obiekt stanu przekazywany do wywołania zwrotnego, czas opóźnienia przed pierwszym wywołaniem wywołania zwrotnego oraz interwał czasu między wywołaniami wywołania zwrotnego wywołań. Aby anulować oczekujący czasomierz, wywołaj metodę Timer.Dispose .

Poniższy przykład tworzy czasomierz, który wywołuje dostarczonego delegata po raz pierwszy po jednej sekundzie (1000 milisekund), a następnie wywołuje go co dwie sekundy. Obiekt stanu w przykładzie służy do liczenia liczby wywołań delegata. Czasomierz jest zatrzymywany, gdy delegat został wywołany co najmniej 10 razy.

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

Aby uzyskać więcej informacji i przykładów, zobacz System.Threading.Timer.

Klasa System.Timers.Timer

Innym czasomierzem, który może być używany w środowisku wielowątkowym, jest to System.Timers.Timer , że domyślnie zgłasza zdarzenie w wątku ThreadPool .

Podczas tworzenia System.Timers.Timer obiektu można określić interwał czasu, w którym ma zostać Elapsed wyświetlone zdarzenie. Enabled Użyj właściwości , aby wskazać, czy czasomierz powinien zgłosić Elapsed zdarzenie. Jeśli chcesz, Elapsed aby zdarzenie było zgłaszane tylko raz po upływie określonego interwału, ustaw wartość AutoResetfalse. Wartość AutoReset domyślna właściwości to true, co oznacza, że Elapsed zdarzenie jest regularnie wywoływane w interwale zdefiniowanym Interval przez właściwość .

Aby uzyskać więcej informacji i przykładów, zobacz System.Timers.Timer.

Klasa System.Threading.PeriodicTimer

Klasa System.Threading.PeriodicTimer umożliwia oczekiwanie na poszczególne znaczniki określonego interwału, wykonując pracę po wywołaniu metody PeriodicTimer.WaitForNextTickAsync.

Podczas tworzenia System.Threading.PeriodicTimer obiektu należy określić, TimeSpan który określa długość czasu między poszczególnymi znacznikami czasomierza. Zamiast przekazywać wywołanie zwrotne lub ustawiać program obsługi zdarzeń, tak jak w poprzednich klasach czasomierza, należy wykonać pracę bezpośrednio w zakresie, oczekując WaitForNextTickAsync na postęp czasomierza przez określony interwał.

Metoda WaitForNextTickAsync zwraca wartość ; true po pomyślnym uruchomieniu czasomierza i false po anulowaniu czasomierza przez wywołanie metody PeriodicTimer.DisposeValueTask<bool>. WaitForNextTickAsync opcjonalnie akceptuje element CancellationToken, co powoduje TaskCanceledException żądanie anulowania.

Aby uzyskać więcej informacji, zobacz System.Threading.PeriodicTimer.

Zobacz też