Утечка памяти при использовании SharedResourceDictionary

если вы работали с некоторыми более крупными wpf-приложениями, вы могли быть знакомы с this . Поскольку ResourceDictionaries всегда создаются, каждый раз, когда они обнаруживаются в XAML, мы можем иметь один словарь ресурсов несколько раз в памяти. Таким образом, вышеупомянутое решение кажется очень хорошей альтернативой. Фактически, для нашего текущего проекта этот трюк очень помог ... Потребление памяти уменьшилось с 800 до 44 МБ, что очень сильно повлияло на него. К сожалению, это решение связано с затратами, которые я хотел бы показать здесь, и, надеюсь, найду способ избежать его, продолжая использовать SharedResourceDictionary .

Я сделал небольшой пример для визуализации проблемы с словарь общих ресурсов.

Просто создайте простое приложение WPF. Добавьте один ресурс Xaml

Shared.xaml



    


Теперь добавьте UserControl. Программный код задан по умолчанию, поэтому я просто показываю xaml

MyUserControl.xaml



    
        
            
                
            
        
    

    
             
    

. Код окна выглядит примерно так

Window1.xaml.cs

// [ ... ]
    public Window1()
    {
        InitializeComponent();
        myTabs.ItemsSource = mItems;
    }

    private ObservableCollection mItems = new ObservableCollection();

    private void OnAdd(object aSender, RoutedEventArgs aE)
    {
        mItems.Add("Test");
    }
    private void OnRemove(object aSender, RoutedEventArgs aE)
    {
        mItems.RemoveAt(mItems.Count - 1);
    }

И окно xaml как это

Window1.xaml

    
        
            
        
    

    
        
            
                

Я знаю, что программа не идеальна и, вероятно, ее можно было бы упростить, но пока я пытался найти способ показать проблему, это то, что я придумал. В любом случае:

Запустите это, и вы проверите потребление памяти, если у вас есть профилировщик памяти, это станет намного проще. Добавьте (с отображением, нажав на вкладку) и удалите страницу, и вы увидите, что все работает нормально. Ничего не протекает. Теперь в разделе UserControl.Resources используйте SharedResourceDictionary вместо ResourceDictionary , чтобы включить Shared.xaml . Вы увидите, что MyUserControl будет храниться в памяти после удаления страницы, а MyUserControl в нем.

Я полагал, что это происходит со всем, что создается через XAML, например конвертеры, пользовательские элементы управления и т.д. Как ни странно, этого не произойдет с пользовательскими элементами управления. Я предполагаю, потому что на самом деле ничего не создается в пользовательских элементах управления, шаблонах данных и т. Д.

Итак, сначала, как мы можем этого избежать? В нашем случае использование SharedResourceDictionary является обязательным, но утечки памяти делают невозможным его эффективное использование. Утечки можно избежать, используя CustomControls вместо UserControls, что не всегда практически. Итак, почему на UserControls сильно ссылается ResourceDictionary? Интересно, почему никто не сталкивался с этим раньше, как я сказал в более старом вопросе, кажется, что мы совершенно неправильно используем словари ресурсов и XAML, иначе мне интересно, почему они такие неэффективные.

Надеюсь, кто-нибудь сможет пролить свет на этот вопрос .

Заранее спасибо Нико

12
задан dowhilefor 28 July 2011 в 10:16
поделиться