4

Visual Studio 2010 で開発された Windows フォーム アプリケーションで奇妙なメモリ バグが発生しています。再現するには、新しい Windows フォーム アプリケーションを起動し、ボタンを追加します。次に、次のコードを貼り付けます。

public Form1()
{
    InitializeComponent();
    AllowDrop = true;
    DragEnter += new DragEventHandler(Form1_DragEnter);
    button1.Click += new EventHandler(button1_Click);
}

private void Form1_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Link;
}

private void button1_Click(object sender, EventArgs e)
{
    for(int i = 1; i <= 100000; i++)
    {
        DataGridView dgv = new DataGridView();  // or any other large object
        if(i % 100 == 0)
            Console.WriteLine("{0}: {1} MB memory in use", i, Environment.WorkingSet / 1024 / 1024);
    }
}

プログラムを実行し、ボタンを押して、出力ウィンドウでメモリ使用量を確認します。ガベージ コレクションが複数のサイクルで発生するため、急激に上昇してから下降します。次に、もう一度実行し、ランダムなファイルまたはフォルダーをフォームにドラッグして、リンク アイコンを取得し、もう一度ボタンを押します。今回は、ガベージ コレクションが呼び出されないか、生成されたすべてのオブジェクトへの有効な参照がまだ存在するなど、メモリ使用量が単調に増加するはずです。

カーソルをリンクのドラッグ アンド ドロップ効果に設定すると、このようなメモリ使用量にどのように影響するのでしょうか?

4

1 に答える 1

3

これは既知のWinFormsリークです。プロパティがTrueに設定されている
場合に発生します。 Falseに設定すると、CLRはメモリをクリアします。 これを回避する最善の方法は、フォームをターゲットのドロップコンテナとして使用しないことです。AllowDrop


プロパティを切り替えるコンテナのような小さなパネルを使用できAllowDropます。

これも機能します。
ドロップ時に、AllowDropをリセットし、ガベージコレクションを強制します。

void Form2_DragDrop(object sender, DragEventArgs e)
    {
        AllowDrop = false;
        GC.Collect();
        GC.Collect();
        AllowDrop = true;
    }
于 2012-05-29T21:00:14.117 に答える