首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF应用程序存在的问题及GUI响应慢

WPF应用程序存在的问题及GUI响应慢
EN

Stack Overflow用户
提问于 2011-03-17 22:26:17
回答 1查看 2K关注 0票数 3

我一直在分析一个WPF应用程序,它基本上从服务器获取数据并在GUI中显示数据。

这段代码不是我的,应用程序有一个与GUI响应缓慢有关的问题,我试图找出问题的原因。

我想和你们分享我对问题的看法,我想听听你们对这个问题的看法,不管这是否有意义。

为了从服务器获取数据,应用程序使用了7个线程(这主要是因为应用程序逻辑,所以不要太注意为什么7而不仅仅是一个.),现在,每个线程都是通过调用一个名为CreateThreadForTask()的方法创建的

代码语言:javascript
复制
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,并将计时器的滴答事件与RunMainSyncForTask()方法链接起来,该方法在内部创建一个后台工作人员,从服务器获取数据并将数据保存到本地数据库。

现在,这是从MSDN中提取的。

在每个Dispatcher循环的顶部重新评估DispatcherTimer。 计时器不能保证在时间间隔发生时准确执行,但保证它们不会在时间间隔发生之前执行。这是因为与其他操作一样,DispatcherTimer操作被放置在Dispatcher队列上。当执行DispatcherTimer操作时,取决于队列中的其他作业及其优先级。

因此,基于这一点,我认为应用程序每次计时器执行滴答事件时都是垃圾线程,这是同时执行7次的;由于DispatcherTimer的性质,所有这些操作都会被添加到Dispatcher队列中,这会使GUI响应慢一些,因为调度程序很忙。

另外,应用程序的另一个问题是,当它运行时,它需要大约90%-95%的CPU,我认为如果我的假设是正确的,这也可能是造成这个问题的原因。

所以如果你能分享一些关于这件事的内幕,我会很感激的。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-03-17 22:40:17

你得到了90%-95%的CPU,因为你已经建立了一种忙碌的方式,通过一个疯狂的线程调用网络等待。

如果您使用此StartSync逻辑发布状态通知或将数据返回到GUI,则需要跳过许多循环。如果您使用的是.Net 4.0,您应该切换到任务并行库,让框架为您处理所有这些。它还支持优雅的取消等。

如果您不希望使用TPL,我建议将WindowDispatcher (使用通常的嫌疑犯: Invoke或BeginInvoke)或SynchronizationContext (与Post异步,与Send同步)传递给各个任务,以便用于这些任务,这些任务必须在GUI中完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5346034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档