WPF管理资源清理(Wpf managed resources cleanup)

2019-10-19 22:46发布

我试图找到清理我的自定义控件可能产生非托管资源的一个很好的方式。 该方案是在父窗口打开,与非托管资源自定义控件子窗口(参见下面的代码)。 这些资源需要清理时CustomControl是不再使用,即当它被内被卸载树(即子窗口关闭),或者从树上取下(即它本身被卸载)

方法1:空载事件时,您手动关闭子窗口此被触发,但如果您关闭父窗口(然后自动关闭子女)

方法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();
    }
}

Answer 1:

在WPF应用程序做到这一点,正确的方法是使用MVVM模式,并从您的视图(控制)和成的ViewModels删除所有逻辑和依赖关系。

你父视图模型将创建一个子视图模型是实现IDisposable ,然后当它去掉了子视图模型,将调用Dispose对孩子视图模型。

如果你的主视图模型有需要清理非托管资源,那么它应该实现IDisposable和一个创建应该承担的责任清洁起来引导程序。

另一个很好的参考是Caliburn.Micro



Answer 2:

你似乎在要求关闭事件。

看看这个:

http://msdn.microsoft.com/en-us/library/system.windows.window_events(v=vs.110).aspx

当窗口关闭时,它会引发两个事件:关闭和封闭。

虽然窗口可以通过在非客户端和客户端领域提供的机制来显式关闭,一个窗口也可以隐含地关闭作为应用程序或Windows的其他部分,包括以下行为的结果:

在用户注销或关闭Windows操作系统。

窗口的所有者关闭(见所有者)。

主要应用窗口关闭ShutdownMode是OnMainWindowClose。

关机时调用。

在所有这些scenarions关闭并关闭事件将被调用。

不同意你的控制Window.Closing事件。 让窗口做的工作。



文章来源: Wpf managed resources cleanup