1

Follow up question from What is a "rooted reference"?

consider this code, for a standard windows application in c#:

Program.cs:

    [STAThread]
    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
        finally
        {
            MessageBox.Show("Bye !");
        }
    }

From1.cs:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Click += new EventHandler(Form1_Click);

    }

    void Form1_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }
}

What makes this form to stay as an rooted reference? Is it because of the Static Main method, i guess it is, or is it anything more to it?

If i just close the form with the X, then the message box will show "bye", but not if i click it. (because of the application.Exit()) - and i think that is strange consider the finally method in main.

So the main question, what makes the form object, stay as an rooted reference so the carbage collector not will kill it?

Community
  • 1
  • 1
Niklas
  • 1,753
  • 4
  • 16
  • 35

2 Answers2

5

The Application.Run method doesn't terminate until your form closes. You pass in your instance of Form1 as a parameter to Run and it becomes a local variable in a method that is currently running, and therefore a root.

Internally Application.Run actually creates an ApplicationContext which holds the reference to the form:

public class ApplicationContext : IDisposable
{
    public Form MainForm
    {
        get { /* ... */ }
        set { /* ... */ }
    }

    public ApplicationContext(Form mainForm)
    {
        this.MainForm = mainForm;
    }

    // ...
}

The ApplicationContext is then given to the RunMessageLoop method.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
2

What roots the instance of Form1 is that if you follow all of the referencing objects back, you will eventually find a reference in a static variable (which is a rooted reference). To follow the path back to the rooted reference:

  • The Form1 instance is stored in an instance field on a newly constructed ApplicationContext instance.
  • That ApplicationContext instance is stored as an instance field on a ThreadContext instance.
  • That ThreadContext instance is stored in a static variable on ThreadContext class <-- ROOTED REFERNCE
Josh
  • 903
  • 8
  • 15
  • True but overcomplicated. in `Foo(new Bar())` the Bar instance is _reachable_ for as long as Foo executes. Simply by being on the stack. – H H Dec 10 '11 at 20:58