Сравнение таймера с DispatcherTimer

98

какая разница between System.Windows.Forms.Timer()а System.Windows.Threading.DispatcherTimer()? В каких случаях мы должны их использовать? какие-нибудь лучшие практики?

парадизонуар
источник

Ответы:

111

Windows.Forms.Timerиспользует цикл сообщений форм Windows для обработки событий таймера. Его следует использовать при записи событий синхронизации, которые используются в приложениях Windows Forms, и вы хотите, чтобы таймер запускался в основном потоке пользовательского интерфейса.

DispatcherTimerэто механизм синхронизации WPF. Его следует использовать, если вы хотите обрабатывать время аналогичным образом (хотя это не ограничивается одним потоком - каждый поток имеет свой собственный диспетчер), и вы используете WPF. Он запускает событие в том же потоке, что и Dispatcher.

В общем, WPF == DispatcherTimerи Windows Forms == Forms.Timer.

При этом есть также System.Threading.Timerтаймер, classкоторый запускается в отдельном потоке. Это хорошо для чисто числового расчета времени, когда вы не пытаетесь обновить пользовательский интерфейс и т. Д.

Рид Копси
источник
1
Спасибо за ваш быстрый ответ. Итак, это означает, что всякий раз, когда я хочу иметь таймер, связанный с пользовательским интерфейсом, я должен использовать DispatcherTimer, а когда я хочу запустить таймер, который я не хочу замораживать UL, я должен использовать System.Threading.Timer в отдельном нить. Второй вопрос: если я хочу использовать DispatcherTimer и хочу, чтобы таймер не был привязан к пользовательскому интерфейсу, следует ли мне вызывать его в отдельном потоке с помощью System.Threading.Timer или все же DisptacherTimer?
paradisonoir
3
Это зависит от того, что вы пытаетесь сделать. Я редко использую System.Threading.Timer - я обычно придерживаюсь Dispatcher Timer, а затем выполняю РАБОТУ (которая может заблокировать ваш пользовательский интерфейс) в другом потоке, используя что-то вроде BackgroundWorker. Таймеры никогда не должны блокировать ваш пользовательский интерфейс, если только вы не делаете «слишком много» работы в их обработчике событий.
Reed Copsey
У меня проблема с DispatcherTimer, со временем съедающей процессор. Есть ли хороший способ справиться с этим?
discorax,
Проверьте, что конкретно съедает процессор. Вы создаете много таймеров, которые не останавливаются?
Рид Копси,
3
Убедитесь, что вы правильно установили свойство interval. Не делайте этого: timer1.Interval = new TimeSpan (1000); // "1000" представляет тики, а не миллисекунды! ЦП был очень загружен, пока я не исправил это следующим образом: timer1.Interval = System.TimeSpan.FromSeconds (1);
Лонни Бест
4

Я нашел здесь хорошую статью о таймерах с небольшими примерами: http://www.progware.org/Blog/post/Timers-in-WPF.aspx

В заключение:

Если DoSomething () манипулирует компонентами графического интерфейса пользователя, то с помощью таймера вам необходимо использовать: this.Dispatcher.Invoke ((Action) delegate {// КОД, СВЯЗАННЫЙ С GUI ЗДЕСЬ}, поскольку вы не можете напрямую обращаться к элементам управления графическим интерфейсом из другого потока. С помощью DispatcherTimer вы делаете не нужно этого делать.

Если DoSomething () выполняет трудоемкую задачу, тогда графический интерфейс в случае DispatcherTimer зависнет. В случае с таймером этого не произойдет, так как длинные методы выполняются в другом потоке.

Seekeer
источник