一个应用程序中有更多DispatcherTimers

时间:2012-02-15 11:30:08

标签: .net wpf multithreading dispatchertimer

我的应用程序表现得像autorefresh。它会检查电子邮件,新视频,笑话等。

我的客户希望这些单个元素以不同的时间间隔进行检查。例如,每分钟发送一次电子邮件,每小时发送一次视频等等。因此,应该可以选择将自己的间隔记录到文本框中,并选中相应的复选框开始/停止刷新。

应用程序是用wpf编写的。我的问题是,是否更好的选择是添加更多DispatcherTimers(DT),每个元素一个或只有一个DT并且在tick函数中make switch?< / p>

另外,我假设DT的tick方法运行主线程。我对吗?如果可能的话,在不同的线程上运行tick方法中的操作会更好吗?

2 个答案:

答案 0 :(得分:3)

尽可能简单。只要检查新元素并不费时,只需使用一个DispatcherTimer,每个元素类别都有自己的Tick处理程序(当然,如果没有数百个类别)。

如果检查操作很耗时,它会阻塞Tick处理程序,从而阻塞UI线程。然后,您可以为每个元素类别使用一个System.Timers.Timer,并在Timer的Elapsed处理程序(而不是Tick)中检查新元素。由于计时器在不同的线程上运行(来自线程池),因此您必须与UI线程同步:

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

private void UpdateUI()
{
    // update UI components
}

答案 1 :(得分:2)

默认情况下,WPF应用程序具有单线程 - 主UI线程和所有UI控件/窗口都已创建并与之关联。在这种情况下,我认为没有任何好处可以使用多个Dispatchers和Dispatcher Timers,因为无论如何Dispatcher Timer会将所有消息委托给关联的Dispatcher的消息循环,这将是一个主UI线程消息循环。

但是如果你在单独的工作线程中创建了一些控件,比如

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

并且也会将消息发布到此窗口 - 然后创建新的Dispatcher并与手动创建的线程关联是有意义的,因此基本上每个Dispatcher都将与自己的线程关联,因此关系是1比1。

关于atick方法 - 它将在与Dispatcher线程相关联的情况下执行。如果您尚未创建与手动创建的工作线程关联的调度程序,则默认情况下WPF Dispatcher与主UI线程关联,

MSDN:

  

使用与System.Timers.Timer相对的DispatcherTimer的原因   是DispatcherTimer在与Dispatcher相同的线程上运行   并且可以在DispatcherTimer

上设置DispatcherPriority