繁体   English   中英

确定是什么阻塞了 UI 线程

[英]Determine what is blocking UI thread

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

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

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

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

  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!

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

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

您可以访问代码分析器吗? 这是他们擅长的类型。 如果答案是否定的,我建议获得一个。

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

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

作为一阶近似,我发现中断调试器(使用 IDE 中的暂停按钮)并查看堆栈很有用。 这样做几次,您可以查看是否有模式。 你总是在同一个函数中吗? 您是否正在为响应事件而做一些昂贵的事情? 您是否收到了更多您期望的活动? 这是低技术,但可以非常有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM