.net中Form的生命周期?

mike77 2007-06-01 03:31:26
在下面的代码中,

private void button1_Click(object sender, EventArgs e)
{
MyForm myForm = new MyForm();
myForm.Show();
}

一般来说,myForm这个对象在button1_Click方法结束后,生命周期便结束,将会被GC清除。但是实际上myForm对应的窗口如果不按右上角“关闭按钮”是不会被GC清除的。为什么GC会对myForm“另眼相看”呢?

对C#和GC理解有限,请各位大侠出手释惑!
...全文
1014 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
as4535 2011-09-01
  • 打赏
  • 举报
回复
<script type='text/javascript' language='javascript'>
alert('123');
</script>
pushouli 2011-07-18
  • 打赏
  • 举报
回复
是因为Application.OpenForms还包含关于窗体的引用
Ivony 2007-06-05
  • 打赏
  • 举报
回复
请问Ivony兄:你说的Reflector是在哪里down的?

我已经发到你邮箱了……
shinaterry 2007-06-01
  • 打赏
  • 举报
回复
用.Net就是为了快速开发...

知道它是一个非托管资源就可以啦....

^o^
mike77 2007-06-01
  • 打赏
  • 举报
回复
看来关于GC还是要结合含有非托管资源对象的特点深入学习一下,才能更好地预料代码的动作。

==================================================================================
引用自phommy(石头,竹子,诗) :
虽然不知道是怎么做的,但的确可以做到

GC.KeepAlive 方法
引用指定对象,使其从当前例程开始到调用此方法的那一刻为止均不符合进行垃圾回收的条件。
北京的雾霾天 2007-06-01
  • 打赏
  • 举报
回复
瞎说
Dispose 没有被执行如何释放
-----------------------------------------


hdt(倦怠) ( ) 信誉:120 Blog 加为好友
说话太过肯定了

你看清了吗...
phommy 2007-06-01
  • 打赏
  • 举报
回复
虽然不知道是怎么做的,但的确可以做到

GC.KeepAlive 方法
引用指定对象,使其从当前例程开始到调用此方法的那一刻为止均不符合进行垃圾回收的条件。
Ivony 2007-06-01
  • 打赏
  • 举报
回复

另:你贴的这些.net自己的代码是怎么看到的?

Reflector
Ivony 2007-06-01
  • 打赏
  • 举报
回复
我觉得在做WinForm的时候,Win32和.NET要区别对待,毕竟他们两个的游戏规则是不同的……。.NET只是对Win32的东西进行了一个封装,那么,我们既要知道这个封装是怎么封的,也要知道封装在里面的东西是怎么运作的。
mike77 2007-06-01
  • 打赏
  • 举报
回复
hdt兄,说的对,我最近就在C+win32 sdk和C#+.NET一块学,感觉win32sdk中窗口的生死过程暴露的比较清楚,而C#+.net要复杂些,因为有GC机制搀和进来,而且还有.net替我们做的工作,比如myForm.Show()等这些
真相重于对错 2007-06-01
  • 打赏
  • 举报
回复
首先退出方法体后,确实被释放了,但释放的是指向对象的指针:myForm,而不是变量指向的内存.

因为Form是引用类型的.因用类型的对象的释放并不是指指向它的指针的释放!
=======================
瞎说
Dispose 没有被执行如何释放
北京的雾霾天 2007-06-01
  • 打赏
  • 举报
回复
MyForm myForm = new MyForm();
myForm.Show();

------------------------------------
首先退出方法体后,确实被释放了,但释放的是指向对象的指针:myForm,而不是变量指向的内存.

因为Form是引用类型的.因用类型的对象的释放并不是指指向它的指针的释放!

真相重于对错 2007-06-01
  • 打赏
  • 举报
回复
从我们这种.net下的使用者角度来看,也只能回答,form不是一个完全的托管资源,不完全受gc控制。
具体的操作,不仅在il层次上,还有更底层因素在里面

mike77 2007-06-01
  • 打赏
  • 举报
回复
hdt兄你说的和Ivony应该是一致的,估计不加Show方法的话,应该是类似一个普通的对象,不过也不敢百分之百保证,因为不知道new f1()的时候到底.net替我们做了些什么。
真相重于对错 2007-06-01
  • 打赏
  • 举报
回复
目前在win32没有退出舞台之前,最好学习一下c 的win32编程,你就会清楚一个windows窗体的生死,这里所谓from只不过是一层包装。具体这个包装如何做,详细地可能需要微软才能回答。
mike77 2007-06-01
  • 打赏
  • 举报
回复
Ivony兄,你动作好快!

这样说来就是因为
Application.OpenFormsInternalAdd(this);
这句话使得myForm的指针并没有丢失,因此GC不会对myForm指向那块堆空间“下毒手”,是不是这样的?

另:你贴的这些.net自己的代码是怎么看到的?
真相重于对错 2007-06-01
  • 打赏
  • 举报
回复
还是不同意楼上,.net把窗体为我们作了封装,不是楼上想的那么简单
不信可以做个试验
form.Dispose( .. )
{
加一句
MessageBox.Show("my clear");
}
from1 f1 = new f1();
//这里不加show
看看什么情况???
mike77 2007-06-01
  • 打赏
  • 举报
回复
To hertcloud :

我理解你的意思,一般都是这样理解的,函数退出以后,堆栈(stack)会清空,myForm生命周期结束,这样myForm所指向的堆(heap)空间便失去指向他指针,垃圾收集器(GC)会在适当时候启动把myForm占用的堆(heap)空间释放。

但是现在的问题是,如果不手动把myForm对应的窗口关闭,我感觉GC应该永远不会清除myForm,这说明myForm这样对象比较特殊,不象一般的对象(比如装箱后int32),为什么会这样呢?就是因为myForm含有非托管资源吗?GC如何判断一个对象含有非托管资源的?。。。



----------------------------------------------------------
hertcloud(·£孙子兵法£·) ( 四星(高级)) 信誉:100 2007-6-1 8:56:32 得分:0
?

如果 楼主 学习过c/c++
这个 是很 容易理解的 事情 虽然C#里面不存在真实的指针 但是 new 一个对象的时候 同样可以看作是对这个对象的动态指针定义.
要知道 局部的 动态指针 是不会在函数结束后 自动消亡的.
这样 就只有等待 GC来回收了.

我的理解是这样 大家共同探讨

Ivony 2007-06-01
  • 打赏
  • 举报
回复
if ( this.dialogResult != DialogResult.OK && (!value || this.CalledMakeVisible) )
{
base.SetVisibleCore(value);
}
else if ( this.GetVisibleCore() != value )
{
if (value)
{
this.CalledMakeVisible = true;
if (this.CalledCreateControl && this.CalledOnLoad)
{
if (!Application.OpenFormsInternal.Contains(this))
{
Application.OpenFormsInternalAdd(this);//关键在这里,真相大白
}
}
}
}

嗯……刚提取错了……
Ivony 2007-06-01
  • 打赏
  • 举报
回复
为了清晰,我们摘出关键代码重新审定逻辑.

if ( this.dialogResult != DialogResult.OK )
{
if ( !value || this.CalledMakeVisible )
{
base.SetVisibleCore(value);
}
else if ( this.GetVisibleCore() != value )
{
if (value)
{
this.CalledMakeVisible = true;
if (this.CalledCreateControl && this.CalledOnLoad)
{
if (!Application.OpenFormsInternal.Contains(this))
{
Application.OpenFormsInternalAdd(this);//关键在这里,真相大白
}
}
}
}
}
加载更多回复(34)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧