Очень большое количество вызовов getvisualchild() моего drawingvisualhost
Привет,
У меня есть проблемы с производительностью с моим DrawingVisualHost. Я пишу приложение, которое обрабатывает файлы MusicXML и рисует музыкальную партитуру (используя загруженную информацию) на холсте.
Простая структура холста ниже:
Основной холст (действует как страница обычно размером с лист бумаги формата А4),
+ Холст для каждой строки музыкальных партитур (до 6-8),
+ Пользовательская панель для упорядочивания элементов (ноты, отдыхает вообще любой музыкальный элемент)
+ Каждый элемент музыкального элемента-это холст с DrawingVisualHost в качестве детей
+ DrawingVisualHost содержит обычно один-два drawingVisuals
Проблема в том, что при перемещении курсора мыши внутри области основного холста при каждом перемещении курсора Я получаю очень большое количество вызовов каждого метода DrawingVisualHost GetVisualChild (int index), которые вызывают очень высокую загрузку процессора при больших коллекциях
Это мой код DrawingVisualHost:
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); } }
Что я уже пробовал:
Я потратил два дня, пытаясь понять, что здесь происходит, код выглядит нормально, никаких исключений, никакого тестирования хитов, никаких MouseEvents, прикрепленных к любому холсту... ничего.
Когда я поместил точку останова внутри этого метода и переместил курсор на основную область холста. Стек вызовов показывает только:
MusicXMLScore.exe!MusicXMLScore.Helpers.DrawingVisualHost.GetVisualChild(int index = 1) Line 25и
[External code]
с выключенным фильтром внешнего кода:
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()