DispatcherTimer по сравнению с обычным Таймером в приложении WPF для планировщика задач

Объясните различие между "DispatcherTimer" и "обычным Таймером", что @Kent Boogaart имел в виду для использования в многопоточности приложение WPF как планировщик задачи в этой теме:

Совет необходим для стратегии многопоточности приложения WPF

в комментариях к одному из сообщения (кавычка):

- Если весь DispatcherTimer делает, начинают другой поток, какой смысл того, чтобы использовать DispatcherTimer?.... те потоки не должны быть запущены на потоке UI. Вы могли просто использовать обычный Таймер и постараться не прерывать UI в целом

Что такое "обычный таймер", который предназначен? Как они ("DispatcherTimer" и "обычный Таймер") отличаются относительно их влияния на UI?

(Пока, читая это сообщение я не думал о DispatcherTimer как естественный способ использовать таймеры в WPF. Каковы случаи, когда это не верно?)

25
задан Community 23 May 2017 в 12:32
поделиться

2 ответа

DispatcherTimer - это обычный таймер. Он запускает свое событие Tick в потоке пользовательского интерфейса, вы можете делать все, что захотите, с пользовательским интерфейсом. System.Timers.Timer - это асинхронный таймер, его событие Elapsed запускается в потоке пула потоков. Вы должны быть очень осторожны в своем обработчике событий, вам не разрешено касаться каких-либо компонентов пользовательского интерфейса или переменных с привязкой к данным. И вам нужно будет использовать оператор блокировки, когда вы обращаетесь к членам класса, которые также используются в потоке пользовательского интерфейса.

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

43
ответ дан 28 November 2019 в 17:47
поделиться

Событие Tick обычного таймера на самом деле запускается в потоке, в котором был создан таймер, поэтому в событии tick, чтобы получить доступ к чему-либо с UI, вам придется пройти через dispatcher.begininvoke, как указано ниже.

RegularTimer_Tick(object sender, EventArgs e)
{
    txtBox1.Text = "count" + i.ToString(); 
    // error can not access
    // txtBox1.Text property outside dispatcher thread...

    // instead you have to write...
    Dispatcher.BeginInvoke( (Action)delegate(){
       txtBox1.Text = "count " + i.ToString();
    });
}

В случае с диспетчерским таймером вы можете получить доступ к элементам пользовательского интерфейса, не выполняя begin invoke или invoke, как указано ниже...

DispatcherTimer_Tick(object sender, EventArgs e)
{
    txtBox1.Text = "Count " + i.ToString();
    // no error here..
}

DispatcherTimer просто предоставляет удобство по сравнению с обычным таймером для легкого доступа к объектам пользовательского интерфейса.

31
ответ дан 28 November 2019 в 17:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: