This article has been localized into Russian by the community.
DispatcherTimer
В WinForms существует компонент Timer, который позволяет выполнять некоторые действия периодически через заданные интервалы времени. В WPF также присутствует такая возможность, однако вместо невидимого компонента формы используется компонент DispatcherTimer. Он работает практически так же, как и Timer, но его не нужно размещать на форме; он создается и используется только в программном коде.
Для использования класса DispatcherTimer необходимо задать интервал времени и подписаться на событие Tick, которое возникает каждый раз при истечении этого интервала. Для запуска таймера DispatcherTimer необходимо вызвать его метод Start() или присвоить true его свойству IsEnabled.
Рассмотрим простой пример использования DispatcherTimer для создания цифровых часов:
<Window x:Class="WpfTutorialSamples.Misc.DispatcherTimerSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DispatcherTimerSample" Height="150" Width="250">
<Grid>
<Label Name="lblTime" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Threading;
namespace WpfTutorialSamples.Misc
{
public partial class DispatcherTimerSample : Window
{
public DispatcherTimerSample()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToLongTimeString();
}
}
}
XAML-код предельно прост: выровненный по центру текст с большим размером шрифта, используемый для отображения текущего времени.
Вся работа выполняется в коде. В коде конструктора окна создаем экземпляр класса DispatcherTimer. Устанавливаем его свойство Intervalравным одной секунде, подписываемся на событие Tick и запускаем таймер, вызывая метод Start(). В обработчике события Tick обновляем содержимое текстовой метки.
DispatcherTimer может работать с различными интервалами времени. Например, вам необходимо, чтобы какие-либо действия выполнялись раз в 30 секунд или, например, раз в 5 минут. В таком случае просто используйте методы TimeSpan.From*, такие как FromSeconds или FromMinutes, либо создайте новый объект TimeSpan с необходимыми параметрами.
Для того, чтобы оценить возможности DispatcherTimer, попробуем обновлять данные чаще. Намного чаще!
using System;
using System.Windows;
using System.Windows.Threading;
namespace WpfTutorialSamples.Misc
{
public partial class DispatcherTimerSample : Window
{
public DispatcherTimerSample()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToString("HH:mm:ss.fff");
}
}
}
Теперь DispatcherTimer срабатывает каждую миллисекунду! В обработчике события Tick используется формат времени, позволяющий отображать миллисекунды. Теперь вы с легкостью можете создать приложение-секундомер. Нужно только добавить несколько кнопок, с помощью которых будут вызываться методы Stop(), Start() и Restart() таймера.
Заключение
DispatcherTimer позволяет легко реализовать периодическое выполнение некоторых действий в приложении. Однако следует помнить о том, что не следует устанавливать слишком маленькие интервалы работы таймера, если в обработчике события Tick выполняются сложные действия. Это может привести к большой нагрузке на компьютер.
Также нужно помнить о том, что DispatcherTimer не всегда обеспечивает абсолютную точность. События таймера помещаются в очередь диспетчера, т.е. если компьютер сильно загружен, то выполнение ваших операций может происходить с задержкой. .NET Framework гарантирует, что событие Tick никогда не возникнет раньше, чем закончится интервал времени, но не гарантирует, что оно не возникнет немного позже. Тем не менее, в большинстве случаев DispatcherTimer обеспечивает более чем достаточную точность.
Если вам необходимо увеличить приоритет вашего таймера в очереди, это можно сделать используя перечисление DispatcherPriority. Более подробно это рассматривается в MSDN article.