WPF性能 - 查找布局传递调用的来源

时间:2017-08-15 10:21:02

标签: wpf performance wpf-controls

有没有办法找出控件的WPF布局传递的原因/内容?

我目前正在跟踪为主要用户控件调用的Arrange Overrides的数量:

public partial class MyView
{
    private ulong _arrangeCount;
    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        Debug.WriteLine($"TTV - ArrangeOverride - {_arrangeCount++}");
        return base.ArrangeOverride(arrangeBounds);
    }
}

加载视图的计数是40!使用复杂的UI(数据网格嵌套,100个单元格和列,单元格,行的自定义模板)这需要几秒钟! (很大一部分时间花在测量/安排上)

有没有办法找出每次传球的来源?

目前我正在从用户控件中删除内容,并试图找出造成这些内容的原因。

我注意到有很多东西存储在有效值中,可能是因为主控制资源字典中的样式/模板中存在绑定?

是否会更新这些有效值(即使其中一些不影响此父控件,会导致调整/安排被调用?)

我已设法将测量大小缓存如下,这似乎在测量方面有所帮助,但是对于排列,我不能做同样的事情,因为在内容绑定后它没有正确排列!

    private Size _lastMeasureConstraint;

    private ulong _measureCount;
    protected override Size MeasureOverride(Size constraint)
    {
        if (_lastMeasureConstraint == constraint)
            return constraint;

        Debug.WriteLine($"TTV - MeasureOverride - {_measureCount++}");
        _lastMeasureConstraint = constraint;
        return base.MeasureOverride(constraint);
    }

大部分措施/安排覆盖的堆栈:

 at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
   at System.Environment.get_StackTrace()

   // This is where I hook in to check how many arrange overrides happen
   at MyAssembly.MyUserControl.ArrangeOverride(Size arrangeBounds) in MyUserControl.cs:line 103
   at System.Windows.FrameworkElement.ArrangeCore(Rect finalRect)
   at System.Windows.UIElement.Arrange(Rect finalRect)
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)

   // This is what makes me think that this is an animation? I could be wrong though!
   at System.Windows.Media.MediaContext.AnimatedRenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority)

   // Dispatcher Wrapper that exposes async/await methods. This is the await state machine
   at MyAssembly.Services.Dispatcher.WpfDispatcher.<Invoke>d__5.MoveNext() in WpfDispatcher.cs:line 37
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at MyAssembly.Services.Dispatcher.WpfDispatcher.Invoke(DispatcherPriority priority, Action action)
   at MyAssembly.Services.Dispatcher.Dispatch.Invoke(DispatcherPriority priority, Action action) in Dispatch.cs:line 176
   at MyAssembly.Services.Dispatcher.Dispatch.P3_ContextIdle(Action action) in Dispatch.cs:line 76

   // This is the top level await, where the async/await state machine starts
   at MyAssembly.MyUserControl.<>c__DisplayClass348_0.<<MyMethod>b__0>d.MoveNext() in MyUserControl.cs:line 3449
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at  MyAssembly.App.Main()

0 个答案:

没有答案