Больше DispatcherTimers в одном приложении - PullRequest
2 голосов
/ 15 февраля 2012

У меня есть приложение, которое ведет себя как автообновление. Он проверяет электронную почту, новые видео, шутки и т. Д.

Мой клиент хочет, чтобы эти одиночные элементы проверялись через разные промежутки времени. Например, электронная почта каждую минуту, видео каждый час и т. Д. Поэтому у него должна быть возможность записывать интервалы самостоятельно в текстовые поля и устанавливая соответствующий флажок запуск / остановка обновления.

Приложение написано в формате wpf. Мой вопрос заключается в том, является ли лучшим вариантом добавить больше DispatcherTimers (DT), по одному для каждого из элементов или использовать только один DT и в тиковой функции сделать переключатель?

Также я предполагаю, что тиковый метод DT запускает основной поток. Я прав? Лучше ли выполнять операции внутри метода тика в другом потоке, если это возможно?

Ответы [ 2 ]

3 голосов
/ 15 февраля 2012

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

Если операция проверки занимает много времени, она заблокирует обработчик Tick и, следовательно, поток пользовательского интерфейса.Тогда вы можете использовать один System.Timers.Timer для каждой категории элементов и выполнять проверку на наличие новых элементов в обработчике Elapsed Таймера (вместо Tick).Поскольку таймеры работают в разных потоках (из пула потоков), вам придется синхронизироваться с потоком пользовательского интерфейса:

private void VideosTimerElapsed(object sender, ElapsedEventArgs e)
{
    // check for new videos...
    Dispatcher.BeginInvoke(new Action(UpdateUI));
}

private void UpdateUI()
{
    // update UI components
}
2 голосов
/ 15 февраля 2012

По умолчанию приложение WPF имеет один поток - основной поток пользовательского интерфейса, и все элементы управления / окна пользовательского интерфейса создаются и связываются с ним.В этом случае я не вижу никаких преимуществ в использовании нескольких диспетчеров и таймеров диспетчера, поскольку в любом случае таймер диспетчера будет делегировать все сообщения в связанный цикл сообщений соответствующего диспетчера, который будет циклом сообщений основного потока пользовательского интерфейса.

Но если вы создали несколько элементов управления в отдельных рабочих потоках, таких как

var thread = new Thread(() => 
         {  
              CustomWindow wnd = new CustomWindow();  
         };

, и также отправили бы сообщения в это окно - тогда имеет смысл создать новый диспетчер и связать его споток, созданный вручную, поэтому в основном каждый Dispatcher будет связан с собственным потоком, поэтому отношение равно 1: 1.

Относительно метода atick - он будет выполняться в связанном с потоком Dispatcher.Если вы не создали диспетчер, связанный с созданным вручную рабочим потоком, то по умолчанию диспетчер WPF, связанный с основным потоком пользовательского интерфейса,

MSDN:

Причины использования DispatcherTimer в отличие от System.Timers.Timer заключаются в том, что DispatcherTimer работает в том же потоке, что и Dispatcher, и DispatcherPriority можно установить для DispatcherTimer

...