4

我在使用 Visual Studio 2010 开发的 Windows 窗体应用程序时遇到了一个奇怪的内存错误。我使用的是 C# 和 .NET 4.0,但我认为这些不是这里的一个因素。要重现,请启动一个新的 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 泄漏。
AllowDrop属性设置为 True 时发生。
如果将其设置为 False,CLR 将清除内存。
避免它的最佳方法是不要将表单用作目标放置容器。

您可以使用像容器这样的小面板来切换AllowDrop属性。

这也将起作用:
在丢弃时,重置 AllowDrop,并强制进行垃圾收集。

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