[Mono-bugs] [Bug 386463] New: Forms are not GCed if a menu is opened

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Sat May 3 20:06:38 EDT 2008


https://bugzilla.novell.com/show_bug.cgi?id=386463


           Summary: Forms are not GCed if a menu is opened
           Product: Mono: Class Libraries
           Version: 1.9.0
          Platform: Macintosh
        OS/Version: Mac OS X 10.4
            Status: NEW
          Severity: Major
          Priority: P5 - None
         Component: Windows.Forms
        AssignedTo: mono-bugs at lists.ximian.com
        ReportedBy: jesjones at mindspring.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---


If Form::Menu is used and the menu is opened the Form won't be GCed. This seems
to be because the popup window isn't removed from the static
NativeWindow::window_collection. One fix for this is to change
MenuTracker::HideSubPopups from:

   PopUpWindow puw = menu.Wnd as PopUpWindow;   
   puw.Hide ();

to:

   menu.Wnd.Hide ();  // note that ShowSubPopup probably needs something
similar
   menu.Wnd.Dispose ();

If Form::MainMenuStrip is used the Form still isn't collected. It looks like
the ToolStripDropDownMenu isn't being removed from the static
NativeWindow::window_collection.

Here's a test case:

#define OLD

// compile with: 
// gmcs -r:System.Windows.Forms.dll -r:System.Drawing.dll -out:app.exe
FormGC2.cs
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

// When running this, be sure to open the file menu.
internal class Program
{
    public static void Main(string[] args)
    {         
        DoInit();

        Application.Run();
    }

     public static void DoInit()
     {         
        ms_timer = new Timer();
        ms_window = new Form();
        ms_window.Closed += DoClosed;
        ms_window.Menu = new MainMenu();
        ms_weak = new WeakReference(ms_window);

#if OLD
            // This works with the patch to MenuTracker::HideSubPopups.
            MenuItem fileMenu = new MenuItem("File");
            fileMenu.MenuItems.Add(0, new MenuItem("Close"));

            ms_window.Menu = new MainMenu();
            ms_window.Menu.MenuItems.Add(fileMenu);

#else
            // This does not work even with the patch. One issue is that
            // a ToolStripDropDownMenu isn't being removed from the static
            // NativeWindow::window_collection.
            MenuStrip strip = new MenuStrip();
            ToolStripMenuItem fileMenu = new ToolStripMenuItem();
            ToolStripMenuItem closeItem = new ToolStripMenuItem();

            // strip
            strip.Items.AddRange(new ToolStripItem[] {fileMenu});

            // fileMenu
            fileMenu.DropDownItems.AddRange(new ToolStripItem[] {closeItem});
            fileMenu.Text = "File";

            // closeItem
            closeItem.Name = "newToolStripMenuItem";
            closeItem.Text = "Close";

            // Form
            ms_window.Controls.Add(strip);
            ms_window.MainMenuStrip = strip;
#endif

        ms_window.Visible = true;

        ms_timer.Tick += DoClose;
        ms_timer.Interval = 3000;
        ms_timer.Start();
    }

    private static void DoClosed(object sender, EventArgs e)
    {
        ms_window = null;
    }

    // Using the close box doesn't work too well so we'll force the 
    // window to close automagically.
    private static void DoClose(Object myObject, EventArgs myEventArgs) 
    {
        if (ms_state == 0)
        {
            Console.WriteLine("0) closing window");
            ms_window.Close();
            ms_state = 1;
        }
        else if (ms_state == 1)
        {
            Console.WriteLine("1) collecting");
            GC.Collect();                        
            ms_state = 2;
        }
        else if (ms_state == 2)
        {
            Console.WriteLine("2) checking");
            if (ms_weak.IsAlive)
                Console.WriteLine("failed: window hasn't been GCed");
            else
                Console.WriteLine("passed: window has been GCed");    
            ms_state = 3;
        }
        else
        {
            Console.WriteLine("3) quitting");
            ms_timer.Stop();
            Application.Exit();
        }
    }

    private static Timer ms_timer;
    private static Form ms_window;
    private static WeakReference ms_weak;
    private static int ms_state;
}


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list