AvalonDock DocumentContent not garbage collected

Viewed 3490

I have created an application that makes use of the AvalonDock framework. A key part is the ability to edit domain-model entities using AvalonDock.DocumentContent derived editors. I hit upon a problem and discovered the my editors are not being garbage collected after they are closed and removed from the DockingManager.Documents collection.

After some fruitless searching I created a small test application that can be recreated in the following manner:

  • In Visual Studio (I'm using 2008), create a new WPF application called AvalonDockLeak;
  • Add a reference to the AvalonDock library (my version is 1.3.3571.0);
  • Add a new UserControl called Document;
  • Change Document.xmal to:

    <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>
    
  • Change Document.xmal.cs to:

    namespace AvalonDockLeak
    {
        using AvalonDock;
    
        public partial class Document : DocumentContent
        {
            public Document()
            {
                InitializeComponent();
            }
    
            ~Document()
            {
            }
        }
    }
    

    The destructor I have added to be able to diagnose the problem adding a breakpoint on the methods opening {, and seeing if it gets hit. It always does on closing the test application but not earlier.

  • Now change Window1.xaml to:

    <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>
    
  • Change Window1.xaml.cs to:

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

This simple application also contains the leak. Which can be observed by the breakpoint on the ~Document() opening { not getting hit after closing a DocumentContent.

Now what I want to now is, is this a known problem and is there a way to prevent it? If the objects are only garbage collected after a long time then what can I do to expedite this? Calling GC.Collect() does not help by the way.

5 Answers
Related