确定什么是阻止UI线程

时间:2010-09-21 09:15:22

标签: .net wpf multithreading user-interface block

我正在开发一个相当大的.NET WPF实时应用程序。该应用程序运行良好且符合预期,除了一个大问题 - UI更新很慢。

这个应用程序是高度事件驱动的,有各种各样的事件引发 - 通过这些事件UI被更新。

这些事件中的一个或多个阻止UI立即显示。完成所有工作后,UI会显示预期结果。

有没有办法确定哪个事件处理程序导致了瓶颈?

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:13)

  public class UIBlockDetector
{
    static Timer _timer;
    public UIBlockDetector(int  maxFreezeTimeInMilliseconds = 200)
    {
        var sw = new Stopwatch();

        new DispatcherTimer(TimeSpan.FromMilliseconds(10), DispatcherPriority.Send, (sender, args) =>
        {
            lock (sw)
            {
                sw.Restart();
            }

        }, Application.Current.Dispatcher);

        _timer = new Timer(state =>
        {
            lock (sw)
            {
                if (sw.ElapsedMilliseconds > maxFreezeTimeInMilliseconds)
                {
                    // Debugger.Break() or set breakpoint here;
                    // Goto Visual Studio --> Debug --> Windows --> Theads 
                    // and checkup where the MainThread is.
                }
            }

        }, null, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(10));

    }

}

在MainWindow构造函数中新建这个类。当断点命中时,您可以转到Visual Studio - >调试 - > Windows - >线程并检查哪些操作阻止了你的UI-Thread!

答案 1 :(得分:8)

我完全支持colithium建议使用分析器。

此外,如果阻止花费的时间超过一秒,您可以在Visual Studio中点击“暂停”按钮。在工具栏中,有一个下拉列表,您可以在其中选择“主线程”。然后它跳转到当前阻止UI的方法。

答案 2 :(得分:5)

您是否可以访问代码分析器?这是他们擅长的东西。如果答案是否定的,我建议你买一个。

除了使用分析器。您可以通过在您怀疑的代码块的开头和结尾放置计时语句来进行“穷人”分析。您甚至可以使用断点并使用挂钟计时。点击什么时会发生问题吗?如果是这样的话就从那没有用户互动,这是一个反复出现的问题吗?然后从计时器开始。

至于实际解决问题......除非违规处理程序正在做一些可以提高效率的事情,否则请考虑采用多线程方法。在这方面,.NET 4.0的新任务库真的很棒。

答案 3 :(得分:1)

作为一阶近似,我发现打破调试器(使用IDE中的暂停按钮)很有用,并查看堆栈。这样做几次,你可以看到是否有模式。你总是在同一个职能部门吗?你是否在为一项活动做些昂贵的事情?您是否收到了更多您期望的活动?它技术含量低,但效果非常好。