таймеры

.NET предоставляет три таймера для использования в многопоточной среде:

  • System.Threading.Timer, который выполняет метод одного обратного вызова в потоке ThreadPool с регулярными интервалами.
  • System.Timers.Timer, который по умолчанию порождает событие в потоке ThreadPool с регулярными интервалами.
  • System.Threading.PeriodicTimer, который позволяет вызывающим выполнять работу после ожидания отдельных галок таймера.

Примечание.

В некоторых реализациях .NET может содержать дополнительные таймеры:

  • System.Windows.Forms.Timer — компонент Windows Forms, который вызывает событие через определенные интервалы времени. У этого компонента нет интерфейса пользователя. Он предназначен для однопоточной среды.
  • System.Web.UI.Timer — компонент ASP.NET, который выполняет асинхронную или синхронную обратную передачу веб-страницы с регулярными интервалами.
  • System.Windows.Threading.DispatcherTimer — таймер, интегрированный в очередь Dispatcher, которая обрабатывается с заданными интервалом и приоритетом.

Класс System.Threading.Timer

Класс System.Threading.Timer позволяет непрерывно вызывать делегат через определенные интервалы времени. Этот класс также можно использовать, чтобы запланировать один вызов делегата через указанный интервал времени. Делегат выполняется в потоке ThreadPool.

При создании объекта System.Threading.Timer вы указываете делегат TimerCallback, который определяет метод обратного вызова, необязательный объект состояния, который передается обратному вызову, временную задержку до первого вызова обратного вызова и интервал времени между вызовами обратного вызова. Чтобы отменить ожидающий таймер, вызовите метод Timer.Dispose.

В следующем примере создается таймер, который вызывает предоставленный делегат в первый раз через одну секунду (1000 миллисекунд), а затем каждые две секунды. Объект состояния в примере используется для подсчета вызовов делегата. Таймер останавливается после 10 вызовов.

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

Дополнительные сведения и примеры см. на сайте System.Threading.Timer.

Класс System.Timers.Timer

Еще один таймер, который может использоваться в многопоточной среде, — System.Timers.Timer. По умолчанию он порождает событие в потоке ThreadPool.

При создании объекта System.Timers.Timer вы можете указать интервал времени, в котором порождается событие Elapsed. Используйте свойство Enabled, чтобы указать, должен ли таймер порождать событие Elapsed. Если вам нужно, чтобы событие Elapsed вызывалось только один раз по истечении заданного интервала, установите для AutoReset значение false. Свойство AutoReset по умолчанию имеет значение true, то есть событие Elapsed вызывается регулярно с интервалом, определенным в свойстве Interval.

Дополнительные сведения и примеры см. на сайте System.Timers.Timer.

Класс System.Threading.PeriodicTimer

Класс System.Threading.PeriodicTimer позволяет ожидать отдельные галочки заданного интервала, выполняя работу после вызова PeriodicTimer.WaitForNextTickAsync.

При создании System.Threading.PeriodicTimer объекта указывается TimeSpan , что определяет продолжительность времени между каждым тиком таймера. Вместо передачи обратного вызова или настройки обработчика событий, как и в предыдущих классах таймера, вы выполняете работу непосредственно в область, ожидая WaitForNextTickAsync продвижения таймера по указанному интервалу.

Метод WaitForNextTickAsync возвращает значение ; true после успешного запуска таймера и false при отмене таймера вызовомPeriodicTimer.DisposeValueTask<bool>. WaitForNextTickAsync При необходимости принимает значение CancellationToken, которое приводит к TaskCanceledException запросу отмены.

Дополнительные сведения см. в разделе System.Threading.PeriodicTimer.

См. также