Что происходит с памятью, когда вкладка удаляет себя из коллекции элементов? - PullRequest
0 голосов
/ 10 апреля 2019

Я собираюсь использовать псевдокод в этом вопросе, поэтому, пожалуйста, обратитесь к этому в теоретическом аспекте (я имею в виду, что будут некоторые упрощения)

Предположим, что такая ситуация:

I MainWindow моего приложения, которое имеет TabControl .Чтобы удалить элемент из его коллекции, я использую static функцию MainWindow следующим образом:

public static void CloseTab(string someKindOfTabIdentity)
{
    var tab = myTabControl.Items.FirstOfDefault(someScenario);
    if (tab != null)
    {
        myTabControl.Items.Remove(tab);
        tab.Content = null;
        tab = null;
        GC.Collect();
    }
}

Теперь у меня есть Page1 , где я разрешаю пользователю закрывать вкладку с помощью некоторой функции, скажем

private void GoToPage2()
{
    MainWindow.CreatePage2AddToTabControlAndNavigateToIt()
    MainWindow.CloseTab(myCurrentPage1Tab);
    App.Cursor = Cursors.Arrow;
}

Эта функция должна создать новую вкладку, назначить ей содержимое, а затем, используя MainWindow.CloseTab(myCurrentPage1Tab);, закрыть текущую вкладку, котораясодержит Page1 .

Вот вопросы:

  1. Что происходит с выделением памяти в Page1 после строки MainWindow.CloseTab(myCurrentPage1Tab);?

  2. Что происходит с выделением памяти Page1 , если после строки MainWindow.CloseTab(myCurrentPage1Tab); есть код?

  3. Когда Page1 будет полностью освобожден из памяти?

  4. Есть ли лучший (более эффективный) способ добиться этого?

Этот упрощенный сценарий - то, что происходит с моим приложением WPF все время, и меня беспокоит, является ли это безопасным способом управления элементами вкладок и памятью моего приложения.

Ответы [ 2 ]

1 голос
/ 10 апреля 2019
  1. Экземпляр Page1 получит право на сборку мусора при условии, что на него не ссылается ни один другой объект, который еще жив.
  2. Ничего лишнего, если только "код после MainWindow.CloseTab(myCurrentPage1Tab); строки" не делает что-то со ссылкой Page1, которая препятствует сбору экземпляра.
  3. Когда сборщик мусора собрал его. Когда это происходит недетерминировано, то есть вы действительно не знаете, когда это произойдет, и вас это не должно волновать.
  4. Ну, нет никаких причин явно вызывать GC.Collect. Это почти всегда плохая идея. При условии, что на экземпляр Page1 больше не ссылаются в вашем приложении, он все равно будет собран , в конечном итоге . Кроме того, я не знаю, почему вы используете статические методы, но я думаю, это другая история.

Подводя итог, вы должны просто убедиться, что в вашем коде нет ссылок, которые бы поддерживали страницу дольше, чем необходимо, но не мешали сборщику мусора.

0 голосов
/ 10 апреля 2019

1-3

Сборщик мусора удалит элементы памяти, на которые нет ссылок, когда это удастся.Точно, когда это произойдет, будет зависеть от того, что еще делает ваше приложение.

Точно, когда какой-то элемент управления очищен коллектором, обычно не имеет значения.Если это так, то, возможно, у вас есть проблема в вашем дизайне.

4

Зависит от того, что вы делаете.Почти все команды разработчиков используют mvvm с wpf.Обычный подход состоит в том, чтобы связать коллекцию моделей представления с источником элементов этого элемента управления вкладками и поместить их во вкладки.Удаление вкладки будет включать удаление модели представления из этого списка.

При таком подходе только пользовательская вкладка будет шаблонизирована в пользовательском интерфейсе.

Хотя ваше описание делает этот звук скорее похожим на навигацию.Обычный шаблон, используемый для навигации в стиле mvvm - это сначала viewmodel (вы должны быть в состоянии найти множество примеров в Google).По сути, это будет включать в себя экспонирование свойства из оконной модели представления, которая будет содержать модель представления для текущего представления.Это будет связано с содержимым Contentcontrol и шаблонно в пользовательский интерфейс на основе типа данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...