krzychu G Ответов: 1

Очень большое количество вызовов 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()

1 Ответов

Рейтинг:
2

krzychu G

Ладно, после последних часов копания я думаю, что нашел причину. Я не знаю почему, но когда я отключил эффект DropShadow, прикрепленный к элементу управления Items, который привязывается к коллекции страниц(основным холстам), проблема, кажется, решена.

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <ItemsControl x:Name="PagesCollection" Margin="0,5,0,5" ItemsSource="{Binding PagesCollection}">
        <!--<ItemsControl.Effect>
            <DropShadowEffect Color="Gray" BlurRadius="5" ShadowDepth="5"/>
        </ItemsControl.Effect>-->
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <helpers:SimpleWrapPanel Margin="10"></helpers:SimpleWrapPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</ScrollViewer>

Итак, теперь у меня есть другой вопрос, Где или как добавить тень к каждому холсту PagesCollection ?