【问题标题】:With WPF, is there a method to detect method calls that are blocking GUI updates?使用 WPF,是否有一种方法可以检测阻止 GUI 更新的方法调用?
【发布时间】:2014-11-05 02:36:40
【问题描述】:

我想知道是否有一些技术或方法可以检测 WPF 应用程序中未使用 async/await 的调用。

我问的原因是我正在开发的 WPF 应用程序在屏幕更新时出现卡顿和停止,我似乎无法追踪阻塞 GUI 线程的调用的来源。

我正在使用带有 MVVM 设计模式的 VS2012 和 VS2013。

【问题讨论】:

标签: wpf xaml asynchronous mvvm-light async-await


【解决方案1】:

我认为performance profiler 在这种情况下可以帮助您。 我个人推荐ANTS profiler,您可以下载试用版并使用它测试您的应用程序。它会告诉您应用程序执行的特定时间段在哪里花费时间。

【讨论】:

    【解决方案2】:

    通常很容易找到阻塞 UI 的原因。可能有 2 种情况 - 要么您在 UI 线程上执行昂贵的操作,您可以测试执行的线程是否是 UI 线程,使用:

    if (Thread.CurrentThread == Dispatcher.CurrentDispatcher.Thread)
    {
        //UI Thread
    }
    

    或者,您正在向许多控件显示并且需要很长时间才能呈现。通常,当列表未虚拟化项​​目时,列表会导致此问题。

    【讨论】:

    • +1 表示列表必须虚拟化项目。这对于提高性能非常重要。
    【解决方案3】:

    您可以订阅 WPF 调度程序的事件来跟踪您的问题。 UI 线程在称为 Dispatcher 的对象中对工作项进行排队。 Dispatcher 按优先级选择工作项并运行每个工作项直至完成。

    要监控 Dispatcher,您可以例如订阅这些操作:

    Dispatcher.Hooks.OperationPosted += Hooks_OperationPosted;
    Dispatcher.Hooks.OperationStarted += Hooks_OperationStarted;
    Dispatcher.Hooks.OperationAborted += Hooks_OperationAborted;
    

    您可以找到完整列表 here

    根据您的问题,您可能会发现使用商业分析器会更好,但通常只需观察调度程序队列即可获得良好的结果。

    【讨论】:

    【解决方案4】:

    这并不能直接回答您的问题,但这将有助于识别调度程序线程何时过载,以下代码使用 DispatcherInactive 事件周围的事件处理程序来计算调度程序线程因工作而过载(阻塞)的时间:

    var maxThreshold = TimeSpan.FromMilliseconds(750);
    var previous = DateTime.Now;
    
         Application.Current.MainWindow
            .Dispatcher.Hooks.DispatcherInactive += (sender, eventArgs) =>
            {
                var current = DateTime.Now;
                var delta = current - previous;
    
                previous = current;
    
                if (delta > maxThreshold)
                {
                    Debug.WriteLine("UI Freeze = {0} ms", delta.TotalMilliseconds);
                }
             };
    

    我建议这仅在调试模式下使用,因此它将被包装在 #if DEBUG 块中。您不希望它在生产环境中运行。

    【讨论】:

    • 这段代码绝对精彩。将其添加到您的代码中,在Debug 行上放置一个断点,如果GUI 线程被阻塞太久,它将立即中断。我希望我对这个答案有更多的投票。
    猜你喜欢
    • 2014-12-13
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多