Таймеры

Самый простой способ выполнять метод периодически – использовать таймер, например класс Timer из пространства имен System.Threading. Этот таймер использует пул потоков, допуская создание множества таймеров без накладных расходов в виде такого же количества потоков. Timer – довольно простой класс с конструктором и парой методов (просто наслаждение для минималистов и авторов книг!).

public sealed class Timer: MarshalByRefObject, IDisposable { public Timer(TimerCallback tick, object state, 1st, subsequent); public bool Change(1st, subsequent); // Для изменения периода public void Dispose(); // Для удаления } // 1st = время до первого срабатывания в миллисекундах или как TimeSpan // subsequent = следующие интервалы в миллисекундах или как TimeSpan // (используйте Timeout.Infinite для одноразового срабатывания)

В следующем примере таймер вызывает метод Tick, который печатает "tick..." по истечении 5 секунд и далее каждую секунду, пока пользователь не нажмет Enter:

using System; using System.Threading; class Program { static void Main() { Timer tmr = new Timer(Tick, "tick...", 5000, 1000); Console.ReadLine(); tmr.Dispose(); // Остановка таймера } static void Tick(object data) { // Этот код выполняется на потоке из пула Console.WriteLine(data); // Печать: "tick..." } }

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

§ Реализация в виде компонента, позволяющая размещать его в дизайнере Visual Studio.

§ Свойство Interval вместо метода Change.

§ Событие Elapsed вместо делегата обратного вызова.

§ Свойство Enabled для запуска и остановки таймера (значение по умолчанию – false).

§ Методы Start и Stop на случай, если вам не нравится Enabled.

§ Флаг AutoReset для указания необходимости периодических срабатываний (значение по умолчанию – true).

Вот пример:

using System; using System.Timers; // Пространство имен Timers вместо Threading class SystemTimer { static void Main() { Timer tmr = new Timer(); // Конструктор без параметров tmr.Interval = 500; tmr.Elapsed += tmr_Elapsed; // Событие вместо делегата tmr.Start(); // Запустить таймер Console.ReadLine(); tmr.Stop(); // Остановить таймер Console.ReadLine(); tmr.Start(); // Продолжить Console.ReadLine(); tmr.Dispose(); // Остановить навсегда } static void tmr_Elapsed(object sender, EventArgs e) { Console.WriteLine("Tick"); } }

.NET Framework предоставляет еще и третий вид таймера – в пространстве имен System.Windows.Forms. Похожий на System.Timers.Timer по интерфейсу, он радикально отличается от него по функциональности. Таймер Windows Forms не использует пула потоков, вместо этого вызывая событие “Tick” всегда в том же самом потоке, в котором был создан таймер. При условии, что таймер создается в главном потоке, там же, где все формы и элементы управления приложения Windows Forms, обработчик события срабатывания таймера может взаимодействовать с формой и элементами управления без нарушения потоковой безопасности и необходимости вызовов Control.Invoke.

Таймер Windows Forms предназначен для заданий, которые могут привести к обновлению пользовательского интерфейса, и которые должны выполняться достаточно быстро. Быстрота выполнения важна, так как событие Tick вызывается в главном потоке, а значит, во время его выполнения интерфейс не будет отвечать на действия пользователя.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: