Поделиться через


Timer Класс

Определение

Создает событие после заданного интервала с возможностью создания повторяющихся событий.

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
Наследование
Реализации

Примеры

В следующем примере создается System.Timers.Timer экземпляр объекта , который вызывает событие Timer.Elapsed каждые две секунды (2000 миллисекунд), настраивает обработчик событий для события и запускает таймер. Обработчик событий отображает значение ElapsedEventArgs.SignalTime свойства при каждом его вызове.

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

Комментарии

Компонент Timer — это серверный таймер, который вызывает Elapsed событие в приложении после истечения времени в миллисекундах Interval в свойстве . Вы можете настроить Timer объект так, чтобы он вызывал событие только один раз или несколько раз с помощью AutoReset свойства . Как правило, Timer объект объявляется на уровне класса, чтобы он оставался в область столько времени, сколько это необходимо. Затем можно обработать его Elapsed событие, чтобы обеспечить регулярную обработку. Например, предположим, что у вас есть критически важный сервер, который должен работать 24 часа в сутки, 7 дней в неделю. Можно создать службу, которая использует объект для периодического Timer проверка сервера и обеспечения работоспособности системы. Если система не отвечает, служба может попытаться перезапустить сервер или уведомить администратора.

Важно!

Класс Timer доступен не для всех реализаций и версий .NET, таких как .NET Standard 1.6 и более ранние версии. В этих случаях вместо этого можно использовать System.Threading.Timer класс .

Этот тип реализует интерфейс IDisposable. По окончании использования выдаленную ему память следует прямо или косвенно освободить. Чтобы сделать это прямо, вызовите его метод Dispose в блоке try/catch. Чтобы сделать это косвенно, используйте языковые конструкции, такие как using (в C#) или Using (в Visual Basic). Дополнительные сведения см. в разделе "Использование объекта, реализующего IDisposable" в статье об интерфейсе IDisposable.

Серверный System.Timers.Timer класс предназначен для использования с рабочими потоками в многопоточной среде. Таймеры сервера могут перемещаться между потоками для обработки вызываемого Elapsed события, что повышает точность, чем таймеры Windows при своевременном вызове события.

Компонент System.Timers.Timer вызывает Elapsed событие на основе значения свойства (в миллисекундах Interval ). Это событие можно обработать для выполнения необходимой обработки. Например, предположим, что у вас есть приложение для онлайн-продаж, которое постоянно публикует заказы на продажу в базе данных. Служба, которая компилирует инструкции по доставке, работает с пакетом заказов, а не обрабатывает каждый заказ по отдельности. Можно использовать для Timer запуска пакетной обработки каждые 30 минут.

Важно!

Класс System.Timers.Timer имеет то же разрешение, что и системные часы. Это означает, что Elapsed событие срабатывает через интервал, определенный разрешением системных часов, если Interval свойство меньше разрешения системных часов. Дополнительные сведения см. в описании свойства Interval.

Примечание

Системные часы, которые используются, — это те же часы, которые используются Командлетом GetTickCount, на которые не влияют изменения, внесенные с помощью timeBeginPeriod и timeEndPeriod.

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

Компонент Timer перехватывает и подавляет все исключения, создаваемые обработчиками событий для Elapsed события. Это поведение может измениться в будущих выпусках платформа .NET Framework. Обратите внимание, что это не относится к обработчикам событий, которые выполняются асинхронно и включают await оператор (в C#) или Await оператор (в Visual Basic). Исключения, создаваемые в этих обработчиках событий, распространяются обратно в вызывающий поток, как показано в следующем примере. Дополнительные сведения об исключениях, создаваемых в асинхронных методах, см. в разделе Обработка исключений.

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

SynchronizingObject Если свойство имеет значение null, Elapsed событие вызывается в потокеThreadPool. Если обработка Elapsed события длится дольше Interval, событие может быть снова вызвано в другом ThreadPool потоке. В этом случае обработчик событий должен быть повторным.

Примечание

Метод обработки событий может выполняться в одном потоке одновременно с тем, что другой поток вызывает Stop метод или задает свойству Enabled значение false. Это может привести к возникновению Elapsed события после остановки таймера. В примере кода для Stop метода показан один из способов избежать этого состояния гонки.

Даже если SynchronizingObject значение не nullравно , Elapsed события могут возникать после Dispose вызова метода или Stop после того, как свойству Enabled было присвоено значение false, так как сигнал для вызова Elapsed события всегда помещается в очередь для выполнения в потоке пула потоков. Одним из способов устранения этого состояния гонки является установка флага, который сообщает обработчику событий о необходимости игнорировать последующие Elapsed события.

Если вы используете System.Timers.Timer класс с элементом пользовательского интерфейса, таким как форма или элемент управления, без размещения таймера в этом элементе пользовательского интерфейса, назначьте форму или элемент управления, содержащий Timer , свойству SynchronizingObject , чтобы событие маршалировало в поток пользовательского интерфейса.

Список значений свойств по умолчанию для экземпляра Timerсм. в конструкторе Timer .

Совет

.NET включает четыре класса с именем Timer, каждый из которых предлагает различные функциональные возможности:

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

Конструкторы

Timer()

Инициализирует новый экземпляр класса Timer и задает всем свойствам начальные значения.

Timer(Double)

Инициализирует новый экземпляр класса Timer и задает свойству Interval указанное значение в миллисекундах.

Timer(TimeSpan)

Инициализирует новый экземпляр Timer класса , присваивая Interval свойству значение указанной точки.

Свойства

AutoReset

Возвращает или задает логическое значение, определяющее, должен ли объект Timer вызывать событие Elapsed один раз (false) или неоднократно (true).

CanRaiseEvents

Возвращает значение, показывающее, может ли компонент вызывать событие.

(Унаследовано от Component)
Container

Возвращает объект IContainer, который содержит коллекцию Component.

(Унаследовано от Component)
DesignMode

Возвращает значение, указывающее, находится ли данный компонент Component в режиме конструктора в настоящее время.

(Унаследовано от Component)
Enabled

Возвращает или задает значение, определяющее, должен ли объект Timer вызывать событие Elapsed.

Events

Возвращает список обработчиков событий, которые прикреплены к этому объекту Component.

(Унаследовано от Component)
Interval

Возвращает или задает интервал в миллисекундах, по истечении которого возникает событие Elapsed.

Site

Возвращает или задает сайт, который привязывает Timer к его контейнеру в режиме конструктора.

SynchronizingObject

Получает или задает объект, используемый для маршалирования вызовов обработчика событий, осуществленных после истечения интервала времени.

Методы

BeginInit()

Начинает во время выполнения инициализацию класса Timer, используемого в форме или другим компонентом.

Close()

Освобождает ресурсы, используемые объектом Timer.

CreateObjRef(Type)

Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом.

(Унаследовано от MarshalByRefObject)
Dispose()

Освобождает все ресурсы, занятые модулем Component.

(Унаследовано от Component)
Dispose(Boolean)

Освобождает все ресурсы, используемые текущим объектом Timer.

EndInit()

Заканчивает во время выполнения инициализацию класса Timer, используемого в форме или другим компонентом.

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetLifetimeService()
Устаревшие..

Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра.

(Унаследовано от MarshalByRefObject)
GetService(Type)

Возвращает объект, представляющий службу, предоставляемую классом Component или классом Container.

(Унаследовано от Component)
GetType()

Возвращает объект Type для текущего экземпляра.

(Унаследовано от Object)
InitializeLifetimeService()
Устаревшие..

Получает объект службы времени существования для управления политикой времени существования для этого экземпляра.

(Унаследовано от MarshalByRefObject)
MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
MemberwiseClone(Boolean)

Создает неполную копию текущего объекта MarshalByRefObject.

(Унаследовано от MarshalByRefObject)
Start()

Начинает вызывать событие Elapsed, задавая для свойства Enabled значение true.

Stop()

Прекращает вызывать событие Elapsed, задавая для свойства Enabled значение false.

ToString()

Возвращает объект String, содержащий имя Component, если оно есть. Этот метод не следует переопределять.

(Унаследовано от Component)

События

Disposed

Возникает при удалении компонента путем вызова метода Dispose().

(Унаследовано от Component)
Elapsed

Происходит по истечении интервала времени.

Применяется к

Потокобезопасность

Все открытые static члены этого типа являются потокобезопасны. Потокобезопасная работа с членами экземпляров типа не гарантируется.

См. также раздел