12

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

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

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

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

4

4 回答 4

23
  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 --> Debug --> Windows --> Threads 并检查哪些操作阻塞了您的 UI-Thread!

于 2014-01-28T16:45:35.457 回答
12

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

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

于 2010-09-21T09:24:10.483 回答
6

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

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

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

于 2010-09-21T09:19:10.257 回答
0

作为一阶近似,我发现中断调试器(使用 IDE 中的暂停按钮)并查看堆栈很有用。多做几次,看看有没有规律。你总是在同一个功能?您是否为响应事件而做一些昂贵的事情?您是否收到了更多您期望的事件?它的技术含量很低,但可能非常有效。

于 2010-09-21T09:22:21.217 回答