AvalonDock DocumentContent not collected garbage

I created an application using the AvalonDock environment. The key part is the ability to edit domain model objects using the AvalonDock.DocumentContent editors received. I ran into a problem and found that my editors are not garbage collected after they are closed and removed from the DockingManager.Documents collection.

After some fruitless search, I created a small test application that can be recreated as follows:

  • In Visual Studio (I'm using 2008), create a new WPF application called AvalonDockLeak ;
  • Add a link to the AvalonDock library (my version 1.3.3571.0);
  • Add a new UserControl named 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 that I added to diagnose the problem by adding a breakpoint when opening the {methods, and seeing if it hits. This always happens when you close the test application, but not before.

  • 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 app also contains a leak. Which can be observed by a breakpoint when opening ~Document() {not getting after closing DocumentContent .

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

+8
garbage-collection c # wpf avalondock
source share
5 answers

I highly recommend you and anyone using AvalonDock 1.3 to upgrade to version 2.0. The latest version is MVVM-friendly and does not suffer from this problem (documents and bindings are correctly garbage collected). Additional information: avalondock.codeplex.com

thanks

+1
source share

obviously, references to your DocumentContent are stored somewhere in the event handler. You must use a memory profiler, such as the CLR-Profiler from microsoft, to determine the cause.

You should ensure that you always unregister a registered event. otherwise, you might get a memory leak. for this you can use the - = operator.

+4
source share

DocumentContent by default hide when closed, which means that the link is stored in memory.

If you want to close the DocumentContent and subsequently delete it, you need to specify a couple of properties in the derived DocumentConcent or change the AvalonDock source.

  this.IsCloseable = true; this.HideOnClose = false; 

Now that it is closed, it will dispose of the link or hang on it, because it is simply hiding.

+3
source share

I also had a problem in this direction. Closing tabs may cause memory leak. I checked it with the profiler, and it turned out that ActiveContent would still save the link, preventing GarbageCollector from clicking.

my code to close the tab:

 dc // DocumentContent, I want to close it documentPane // DocumentPane, containing the dc documentPane.Items.Remove(dc); 

it made me close the tab, but found out that I need to call

 dc.Close(); 

before deleting content from DocumentPane if I want ActiveContent to be set to null and let GC do the job.

Note: I am using version 1.2 of AvalonDock, this can be changed in newer versions.

+2
source share

It looks like a long time outstanding error ...:

http://avalondock.codeplex.com/workitem/9113

+1
source share

All Articles