4

I am encountering a bizarre memory bug with a Windows Forms application developed in Visual Studio 2010. I am using C# and .NET 4.0 but I don't think those are a factor here. To reproduce, start a new Windows Forms Application and add a button. Then paste in the following code:

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

Run the program, hit the button, and watch the memory usage in the output window. It spikes up and then falls back down as garbage collection occurs in multiple cycles. Then run it again, drag any random file or folder onto the form until you get the link icon, and then hit the button again. This time the memory usage should increase monotonically, like garbage collection is not getting called or there are still valid references to all the objects generated.

How could setting the cursor to the link drag-drop effect affect memory usage like this???

Craig W
  • 4,390
  • 5
  • 33
  • 51
  • Is your question really about *Visual Studio*, or is it about C#/Winforms? – Andrew Barber May 04 '12 at 00:37
  • WinForms I suppose, but I am pretty sure it is not specific to C#. – Craig W May 04 '12 at 00:38
  • My point was it seems you are talking about a memory leak in your program - not in Visual Studio. What is the magnitude of the memory in question here, at each one of the points you mention in your post? – Andrew Barber May 04 '12 at 00:40
  • I have clarified that it is a WinForms issue more than VS. And the memory leak is significant, several hundred MB in the example here. In the real-world situation where I encountered this I am easily running out of memory. – Craig W May 04 '12 at 00:44
  • I verified that this occurs. However, if you do DragDropEffects.None it does not cause the memory leak. – Moop May 04 '12 at 02:07

1 Answers1

3

This is a known WinForms leak.
Happens when the AllowDrop property is set to True.
If you set it to False, the CLR will clear the memory.
Best way to avoid it is not to use the form as the target drop container.

You can use a small panel like container that toggles the AllowDrop property.

This will also work:
On drop, reset the AllowDrop, and force garbage collection.

void Form2_DragDrop(object sender, DragEventArgs e)
    {
        AllowDrop = false;
        GC.Collect();
        GC.Collect();
        AllowDrop = true;
    }
Erez Robinson
  • 794
  • 4
  • 9
  • The latter solution didn't seem to help. Also, do you have reference documenting this as a known WinForms leak? – Craig W May 29 '12 at 22:49
  • I've known this leak for some time now, but microsoft bug tracking set it on "Won't Fix", I don't know why. I only found a few sites discussing this problem, you can view this page: http://stackoverflow.com/questions/620733/memory-leak-in-c-sharp But I strongly suggest not using the form as a drop destination, that would simplify everything. – Erez Robinson Jun 18 '12 at 22:03