代码之家  ›  专栏  ›  技术社区  ›  Contango

对于WPF,是否有一种方法可以检测阻止GUI更新的方法调用?

  •  3
  • Contango  · 技术社区  · 10 年前

    我想知道是否有一些技术或方法可以检测WPF应用程序中没有使用异步/等待的调用。

    我问的原因是,我正在开发的WPF应用程序在屏幕更新时断断续续,而且我似乎无法找到阻塞GUI线程的调用源。

    我将VS2012和VS2013与MVVM设计模式一起使用。

    4 回复  |  直到 9 年前
        1
  •  8
  •   AwkwardCoder    10 年前

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

    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 块你不希望这在生产中运行。

        2
  •  1
  •   Moti Azu    10 年前

    我想 performance profiler 在这种情况下可以帮助你。 我个人建议 ANTS profiler ,您可以下载试用版并使用它测试您的应用程序。它会告诉您应用程序执行的某个时间段在哪里度过。

        3
  •  1
  •   Novitchi S    10 年前

    通常,很容易发现是什么阻塞了UI。有两种情况-要么在UI线程上执行昂贵的操作,要么使用以下方法测试执行的线程是否为UI线程:

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

    或者,显示给许多控件,渲染需要很长时间。通常,当列表未虚拟化项目时,列表会导致此问题。

        4
  •  1
  •   Postlagerkarte    10 年前

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

    要监视Dispatcher,您可以订阅以下操作:

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

    你找到了一个完整的列表 here .

    根据您的问题,您可能会发现自己更适合使用商业探查器,但通常只需观察分派器队列即可获得良好的结果。