我创建了一个使用AvalonDock框架的应用程序。一个关键部分是使用AvalonDock.DocumentContent派生的编辑器来编辑域模型实体的能力。我碰到一个问题,发现关闭并从DockingManager.Documents集合中删除后,我的编辑器没有被垃圾回收。

经过一番无能为力的搜索之后,我创建了一个小型测试应用程序,可以按以下方式重新创建它:

  • 在Visual Studio(我正在使用2008)中,创建一个名为AvalonDockLeak的新WPF应用程序;
  • 添加对AvalonDock库的引用(我的版本是1.3.3571.0);
  • 添加一个名为Document的新UserControl;
  • 将Document.xmal更改为:
    <ad:DocumentContent x:Class="AvalonDockLeak.Document"
                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock">
        <Grid>
            <TextBox />
        </Grid>
    </ad:DocumentContent>
    
  • 将Document.xmal.cs更改为:
    namespace AvalonDockLeak
    {
        using AvalonDock;
    
        public partial class Document : DocumentContent
        {
            public Document()
            {
                InitializeComponent();
            }
    
            ~Document()
            {
            }
        }
    }
    

    我添加的析构函数可以诊断问题,在打开{的方法上添加断点,并查看是否被命中。它总是在关闭测试应用程序时执行,但不会更早。
  • 现在将Window1.xaml更改为:
    <Window x:Class="AvalonDockLeak.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
            Title="Memory Leak Test" Height="300" Width="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Name="NewButton" Click="NewButton_Click" Content="New" Height="26" Width="72" />
            <ad:DockingManager x:Name="DockManager" Grid.Row="1">
                <ad:DocumentPane />
            </ad:DockingManager>
        </Grid>
    </Window>
    
  • 将Window1.xaml.cs更改为:
    namespace AvalonDockLeak
    {
        using System.Windows;
    
        public partial class Window1 : Window
        {
            private int counter = 0;
    
            public Window1()
            {
                InitializeComponent();
            }
    
            private void NewButton_Click(object sender, RoutedEventArgs e)
            {
                string name = "Document" + (++this.counter).ToString();
                var document = new Document()
                {
                    Name = name,
                    Title = name,
                    IsFloatingAllowed = false
                };
    
                document.Show(this.DockManager);
                document.Activate();
            }
        }
    }
    

  • 这个简单的应用程序还包含泄漏。可以通过打开~Document()上的断点观察到这一点{在关闭DocumentContent之后没有被击中。

    现在我想知道的是,这是一个已知问题,有没有办法防止它发生?如果对象只是经过很长一段时间的垃圾收集,那么我该怎么做以加快速度呢?顺便说一句,调用GC.Collect()并没有帮助。

    最佳答案

    我强烈建议您和任何使用AvalonDock 1.3升级到2.0版的人。
    最新版本是MVVM友好的,并且不会遇到此问题(正确地对文档和可 anchor 对象进行了垃圾回收)。
    更多信息:avalondock.codeplex.com

    谢谢

    关于c# - AvalonDock DocumentContent没有被垃圾收集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6705343/

    10-09 07:01