8

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()を呼び出しても役に立ちません。

4

5 に答える 5

3

デフォルトでは、閉じると非表示になります。DocumentContentこれは、参照が存続することを意味します。

DocumentContentを閉じてから破棄する場合は、派生内でいくつかのプロパティを指定するか、ソースを変更する必要がありますDocumentConcentAvalonDock

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

閉じられると、参照が単に隠されているため、参照に固執するのではなく、参照が破棄されます。

于 2011-11-30T17:01:05.613 に答える
1

This looks like a long time outstanding bug...:

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

于 2012-02-24T14:29:43.723 に答える
1

AvalonDock 1.3 を使用している方は、バージョン 2.0 にアップグレードすることを強くお勧めします。最新バージョンは MVVM に対応しており、この問題の影響を受けません (ドキュメントとアンカー可能オブジェクトは正しくガベージ コレクションされます)。詳細: avalondock.codeplex.com

ありがとう

于 2012-11-18T21:44:32.543 に答える
1

この方向にも問題がありました。タブを閉じると、メモリ リークが発生することがありました。プロファイラーで確認したところ、ActiveContentがまだ参照を保持しているため、GarbageCollector が開始されないことがわかりました。

タブを閉じるための私のコード:

dc // DocumentContent, I want to close it
documentPane // DocumentPane, containing the dc

documentPane.Items.Remove(dc);

これでタブを閉じることができましたが、呼び出す必要があることがわかりました

dc.Close();

ActiveContentnullに設定し、GC にその仕事をさせたい場合は、documentPane からコンテンツを削除する前に。

注:私は AvalonDock のバージョン 1.2 を使用していますが、これは新しいバージョンでは変更されている可能性があります。

于 2012-01-17T10:38:19.813 に答える