我一直在分析一个WPF应用程序,它基本上从服务器获取数据并在GUI中显示数据。
此代码不是我的,并且应用程序存在与GUI响应缓慢相关的问题,我正试图找到导致该问题的原因。
我想与你分享我对这个问题的看法,我想听听你对它的看法,是否有意义。
要从服务器获取数据,应用程序使用7个线程(这样做主要是因为应用程序逻辑,所以不要过多关注为什么7而不只是一个......)现在,每个线程都是通过调用一个名为CreateThreadForTask()
的方法创建的public void StartAllThreads()
{
this.CreateThreadForTask(Tasks.Task1);
this.CreateThreadForTask(Tasks.Task2);
this.CreateThreadForTask(Tasks.Task3);
this.CreateThreadForTask(Tasks.Task4);
this.CreateThreadForTask(Tasks.Task5);
this.CreateThreadForTask(Tasks.Task6);
this.CreateThreadForTask(Tasks.Task7);
}
public void CreateThreadForTask(Tasks task)
{
... // this part of the code is not important
//! Initialize and start timer
timer = null;
timer = new DispatcherTimer();
timer.Tick += new EventHandler(RunMainSyncForTask);
timer.Start();
}
public void RunMainSyncForTask(object s, EventArgs e)
{
int sec = int.Parse(AppSettings.GetSetting("syncInterval"));
timer.Interval = new TimeSpan(0, 0, sec);
//threadCaller is a background worker
threadCaller = InitializeThread();
threadCaller.DoWork += DoWorkEventHandler(StartSync);
threadCaller.RunWorkerAsync();
}
当我调试代码时,我注意到所有线程都是使用DispatcherTimer创建的;我认为应用程序正在创建7个DispatcherTimer,并将定时器的Tick事件与RunMainSyncForTask()方法链接在一起,里面创建一个后台工作程序,从服务器获取数据并将该数据保存到本地数据库。
现在,这是从MSDN中获取的
DispatcherTimer在每个Dispatcher循环的顶部重新评估。
不保证定时器在时间间隔发生时准确执行,但保证在时间间隔发生之前不执行定时器。这是因为DispatcherTimer操作与其他操作一样放在Dispatcher队列中。 DispatcherTimer操作执行时依赖于队列中的其他作业及其优先级。
因此,基于此我认为应用程序每次定时器执行tick事件时都会发送垃圾邮件,并且同时执行7次;由于DispatcherTimer的性质,所有这些操作都被添加到Dispatcher队列中,由于Dispatcher忙,因此GUI响应变慢。
此外,该应用程序的另一个问题是,当它运行时,它占用了大约90-95%的CPU,我认为如果我的假设是正确的,这也可能是造成这个问题的原因。
所以,如果你可以分享一些内容,我会很感激。
感谢。
答案 0 :(得分:1)
你获得了90-95%的CPU,因为你已经设置了一种繁忙的等待通过一个疯狂的线程调用网络。
如果您使用此StartSync
逻辑发布状态通知或将数据返回到GUI,那么您就会遇到很多困难。如果你在.Net 4.0上,你应该切换到Task Parallel Library并让框架为你处理所有这些。它还支持优雅的取消等。
如果你不想使用TPL,我建议改为传递Window
s Dispatcher
(使用通常的嫌疑人:Invoke或BeginInvoke)或SynchronizationContext
(与Post
异步{1}},与Send
同步,用于必须在GUI中完成的用于这些任务的各个任务。