什么使表格成为根本参考?

时间:2011-12-10 19:26:19

标签: c# reference clr

来自What is a "rooted reference"?

的问题

考虑此代码,对于c#中的标准Windows应用程序:

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

是什么让这个表单作为根本参考保留? 是因为Static Main方法,我想是的, 还是它还有什么呢?

如果我只是用X关闭表单,那么消息框将显示“bye”, 但如果我点击它不会。 (因为application.Exit()) - 我认为 奇怪的是考虑main中的finally方法。

所以主要的问题是,什么使形式对象,作为一个根的参考,所以垃圾收集器不会杀死它?

2 个答案:

答案 0 :(得分:5)

Application.Run方法在表单关闭之前不会终止。您将Form1的实例作为参数传递给Run,它变为当前正在运行的方法中的局部变量,因此也是根。

内部Application.Run实际创建了ApplicationContext,其中包含对表单的引用:

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

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

    // ...
}

然后将ApplicationContext提供给RunMessageLoop方法。

答案 1 :(得分:2)

Form1的实例的根源是,如果您追溯所有引用对象,您最终将在静态变量(这是一个有根引用)中找到引用。要按照路径返回到有根参考:

  • Form1实例存储在新构建的ApplicationContext实例的实例字段中。
  • ApplicationContext实例作为实例字段存储在ThreadContext实例上。
  • ThreadContext实例存储在ThreadContext类< - ROOTED REFERNCE
  • 上的静态变量中