Wpf управляемая очистка ресурсов

Я пытаюсь найти хороший способ очистки неуправляемых ресурсов, которые могут генерировать мои пользовательские элементы управления. В этом сценарии родительское окно открывает дочернее окно с пользовательским элементом управления с неуправляемыми ресурсами (см. Код ниже). Эти ресурсы необходимо очистить, когда CustomControl больше не используется, т.е. когда дерево, в котором оно находится, выгружено (т.е. дочернее окно закрывается), или оно удалено из дерева (т.е. оно само выгружено)

Способ 1: событие Unloaded Это срабатывает при закрытии дочернего окна вручную, но не при закрытии родительского окна (которое затем автоматически закрывает дочерние окна).

Метод 2: OnVisualChildrenChanged Это не вызывается, когда дочернее окно закрывается вручную или автоматически родительским элементом, и используется только в том случае, если CustomControl перемещается в другой родительский элемент.

Метод 3: Dispatcher.ShutdownStarted Это не очень помогает, поскольку пользователь, возможно, открыл / закрыл несколько дочерних окон до того, как они закончили работу с приложением, а очистка памяти только в конце не достаточна.

Способ 4. Сделайте так, чтобы CustomControl подписывался на ChildWindow.Closing. Этого тоже недостаточно, элемент управления не должен знать, что он находится в окне.

Метод 5: Финализатор Страдает от той же проблемы, что и Метод 3, может пройти некоторое время, прежде чем он будет вызван

public class CustomControlWithManagedResources : Control
{
    ~CustomControlWithManagedResources()
    {
        Console.WriteLine("~CustomControlWithManagedResources");
    }

    public CustomControlWithManagedResources()
    {
        Unloaded += CustomControl_Unloaded;
        Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    }

    void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    {
        Console.WriteLine("ShutdownStarted");
    }

    void CustomControl_Unloaded(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("Unloaded");
    }

    protected override void OnVisualParentChanged(DependencyObject oldParent)
    {
        base.OnVisualParentChanged(oldParent);

        if(oldParent != null)
            Console.WriteLine("OnVisualParentChanged");
    }
}

public class ChildWindow : Window
{
    public ChildWindow()
    {
        Content = new CustomControlWithManagedResources();
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
    {
        base.OnMouseDoubleClick(e);
        new ChildWindow() { Owner = this }.Show();
    }
}

2 ответа

Решение

Правильный способ сделать это в приложении WPF - использовать шаблон MVVM и удалить всю логику и зависимости из ваших представлений (элементов управления) и в ViewModels.

Ваш родительский ViewModel создаст дочерний ViewModel, который реализован IDisposable а затем, когда он удаляет дочернюю ViewModel, он будет вызывать Dispose на дочернюю ViewModel.

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

Еще одна хорошая ссылка Caliburn.Micro

Вы, кажется, спрашиваете о закрытии мероприятия.

Взгляните на это:

http://msdn.microsoft.com/en-us/library/system.windows.window_events%28v=vs.110%29.aspx

Когда окно закрывается, оно вызывает два события: закрытие и закрытие.

Хотя окно может быть явно закрыто с помощью механизмов, предоставляемых в областях, не связанных с клиентом и клиентом, окно также может быть неявно закрыто в результате поведения в других частях приложения или Windows, включая следующие:

Пользователь выходит из системы или закрывает Windows.

Владелец окна закрывается (см. Владелец).

Главное окно приложения закрыто, а ShutdownMode - OnMainWindowClose.

Отключение называется.

Во всех этих сценариях будут вызываться события закрытия и закрытия.

Не подписывайте свой элемент управления на событие Window.Closing. Позвольте Окну сделать работу.

Другие вопросы по тегам