WPF管理的资源清理 [英] Wpf managed resources cleanup

查看:261
本文介绍了WPF管理的资源清理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试寻找一种清除自定义控件可能生成的非托管资源的好方法.在这种情况下,父窗口将打开一个子窗口,该子窗口具有带有非托管资源的自定义控件(请参见下面的代码).当不再使用CustomControl时,即当其内的树被卸载(即,子窗口关闭),或从树中将其删除(即,其本身被卸载)时,需要清理这些资源.

I'm trying to find a good way of cleaning up unmanaged resources that my custom controls may generate. The scenario is in which the parent window opens a child window that has a custom control with unmanaged resources (see code below). These resources need to be cleaned up when the CustomControl is no longer in use, i.e when the tree it is within is unloaded (i.e the child window closes), or it is removed from a tree (i.e it itself is unloaded)

方法1:卸载事件 当您手动关闭子窗口时会触发此事件,但是如果您关闭父窗口(然后会自动关闭子窗口),则不会触发该事件

Method 1 : Unloaded event This gets triggered when you close a child window manually, but not if you close the parent window (which then automatically closes the children)

方法2:OnVisualChildrenChanged 当子窗口由父级手动或自动关闭时,不会调用此方法,仅当CustomControl移到另一个父元素时才有用.

Method 2 : OnVisualChildrenChanged This doesn't get called when the child window is closed manually or automatically by the parent, and is only of use if the CustomControl is moved to a different parent element.

方法3:Dispatcher.ShutdownStarted 这并不是什么真正的帮助,因为用户可能在完成应用程序之前已经打开/关闭了几个子窗口,并且仅在最后清理内存是不够的.

Method 3 : Dispatcher.ShutdownStarted This isn't really much help as the user may have opened/closed several child windows before they finish with the app, and having that memory only cleaned up at the end isn't good enough.

方法4:让CustomControl订阅ChildWindow.Closing 这也不够好,..控件不必不必知道它在窗口中.

Method 4 : Have the CustomControl subscribe to ChildWindow.Closing This isn't good enough either, .. the control shouldn't have to know that it is in a window.

方法5:终结器 遭受与方法3相同的问题,..可能要过一会儿才能被调用

Method 5 : Finalizer Suffers from same issue as Method 3, .. it could be a while before its called

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

推荐答案

在WPF应用程序中执行此操作的正确方法是使用

The right way to do this in a WPF application is to use the MVVM pattern and to remove all logic and dependencies from your Views (controls) and into ViewModels.

您的父级ViewModel将创建一个实现了IDisposable的子级ViewModel,然后在删除该子级ViewModel时,将在子级ViewModel上调用Dispose.

Your parent ViewModel would create a child ViewModel that implemented IDisposable and then when it removed the child ViewModel it would call Dispose on the child ViewModel.

如果主ViewModel具有需要清理的非托管资源,则应实现IDisposable,并且创建的引导程序应负责清理这些资源.

If your main ViewModel has unmanaged resources that need to be cleaned up, then it should implementIDisposable and the bootstrapper that creates that should take responsibility for cleaning them up.

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

这篇关于WPF管理的资源清理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆