来自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方法。
所以主要的问题是,什么使形式对象,作为一个根的参考,所以垃圾收集器不会杀死它?
答案 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