Hi,
I have performance problem with my DrawingVisualHost. I'm writing an application which processing MusicXML files and draws music score (using loaded information) on Canvas.
Simple Canvas structure below:
Main Canvas (acts like page usually size of A4 paper of sheet),
+ Canvas for each line of music scores (up to 6-8),
+ Custom panel to arrange items(notes,rests generally any music item)
+ Each music element item is Canvas with DrawingVisualHost as children
+ DrawingVisualHost contains usually one-two drawingVisuals
The problem is when I'm moving mouse cursor inside area of Main Canvas on every cursor move I'm getting very large amount of calls to every DrawingVisualHost GetVisualChild(int index) method which cause very high CPU usage with large collections
This is my DrawingVisualHost code:
public class DrawingVisualHost : FrameworkElement
{
private List<Visual> visuals;
public DrawingVisualHost()
{
visuals = new List<Visual>();
IsHitTestVisible = true;
}
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
protected override int VisualChildrenCount
{
get
{
return visuals.Count;
}
}
public void AddVisual(Visual visual)
{
visuals.Add(visual);
AddVisualChild(visual);
}
}
What I have tried:
I've spent two days trying to understand what is going on here, code looks ok, no exceptions, no Hit testing, no MouseEvents attached to any Canvas... nothing.
When I placed breakpoint inside this method and I moved cursor on Main Canvas area. Call stack shows only:
MusicXMLScore.exe!MusicXMLScore.Helpers.DrawingVisualHost.GetVisualChild(int index = 1) Line 25
and
[External code]
with External code filter off:
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.VisualDescendantBounds.get()
PresentationCore.dll!System.Windows.Media.Visual.TrySimpleTransformToAncestor(System.Windows.Media.Visual ancestor = {MusicXMLScore.MainWindow}, bool inverse = true, out System.Windows.Media.GeneralTransform generalTransform = null, out System.Windows.Media.Matrix simpleTransform = {System.Windows.Media.Matrix})
PresentationCore.dll!System.Windows.Input.InputElement.TranslatePoint(System.Windows.Point pt, System.Windows.DependencyObject from, System.Windows.DependencyObject to, out bool translated = false)
PresentationCore.dll!System.Windows.Input.InputElement.TranslatePoint(System.Windows.Point pt, System.Windows.DependencyObject from, System.Windows.DependencyObject to)
PresentationCore.dll!System.Windows.Input.MouseDevice.PreNotifyInput(object sender, System.Windows.Input.NotifyInputEventArgs e = {System.Windows.Input.NotifyInputEventArgs})
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea()
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input)
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport)
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel)
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd = {System.IntPtr}, MS.Internal.Interop.WindowMessage msg = WM_MOUSEFIRST, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false)
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd = {System.IntPtr}, int msg = 512, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false)
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = {System.IntPtr}, int msg = 512, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false)
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler = null)
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = {System.IntPtr}, int msg = 512, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr})
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame})
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame)
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window)
PresentationFramework.dll!System.Windows.Application.Run()
MusicXMLScore.exe!MusicXMLScore.App.Main()
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args)
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()