static class Program {
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main() {
B b = new B(new A());
Console.Read();
b = null;//运行此代码后b之前引用的对象被释放
Thread.Sleep(3500 * 1000);
} public class A {
private event EventHandler m_testEvent;
public event EventHandler TestEvent {
add {
this.m_testEvent += value;
}
remove {
this.m_testEvent -= value;
}
}
} public class B {
public B(A a) {
this.m_a = a;
this.m_a.TestEvent += delegate(Object sender,EventArgs e) {
this.process();
};
this.m_a.TestEvent += new EventHandler(m_a_TestEvent);
} private A m_a; void m_a_TestEvent(object sender,EventArgs e) {
this.process();
} private void process() {
for(int i = 0;i >= 0;i++) {
}
}
}
} 代码有点长 :)
简单的讲:A对象是B对象的成员变量,在B的构造函数中又注册了A对象的事件;
这样似乎造成了A、B的循环引用,但垃圾回收还是将B对象回收了。
不清楚为什么B对象会被回收,有兴趣的一起讨论讨论 :D
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main() {
B b = new B(new A());
Console.Read();
b = null;//运行此代码后b之前引用的对象被释放
Thread.Sleep(3500 * 1000);
} public class A {
private event EventHandler m_testEvent;
public event EventHandler TestEvent {
add {
this.m_testEvent += value;
}
remove {
this.m_testEvent -= value;
}
}
} public class B {
public B(A a) {
this.m_a = a;
this.m_a.TestEvent += delegate(Object sender,EventArgs e) {
this.process();
};
this.m_a.TestEvent += new EventHandler(m_a_TestEvent);
} private A m_a; void m_a_TestEvent(object sender,EventArgs e) {
this.process();
} private void process() {
for(int i = 0;i >= 0;i++) {
}
}
}
} 代码有点长 :)
简单的讲:A对象是B对象的成员变量,在B的构造函数中又注册了A对象的事件;
这样似乎造成了A、B的循环引用,但垃圾回收还是将B对象回收了。
不清楚为什么B对象会被回收,有兴趣的一起讨论讨论 :D
解决方案 »
- C#如何调用带lib库的jar
- VS2010 报表rdlc添加数据集无法添加其他目录下的,只能添加根目录的数据集?
- 现在比较有名的有哪几款框架?
- 怎么获取listbox里面的选中项
- DeveloperExpress的XtraGrid,当焦点移到某个单元格时,如何让该单元格高亮显示?
- 请问如何给一个虚拟目录修改名字???????
- 求解:webbrowser 控件无法导航到使用跳转的地址
- 二次求助,treeView操作的报错,大虾帮帮
- 请高手解答!!!!
- using (IDbDataAdapter dataAdapter = this.GetDataAdapter())
- listView小问题
- c# winform里如何获取有焦点的控件
关B是否 释放有什么关系.
比如说你是一家商店的会员,你开通了新品通知业务(就是有什么新品会及时通知你)
然后突然一天,商店被政府给查封关门了.(就象你在程序中把 b=null )你就奇怪了,他怎么关门了呢?
是不是只要你还是人家的会员,只要你开通了服务人家就永远不能被查封呢.不相关的
这么说不知道你明白不..
我是通过内存工具查看发现b被回收的,那个工具在内部调用了GC.Collect()。to:birdlonger
.net判断垃圾回收的策略就是检测对象是否被引用吧;在这个例子中,b对象注册了a对象的事件,所以b对象被a对象引用了。
这样b对象就处于被引用状态,按道理是不会被回收的。但真实情况是b被回收了。
详细的引用关系应该是: a 引用了 EventHandler委托,EventHandler委托 引用了 b,b 引用了 a。(EventHandler委托是a的事件类型)
实际的运行情况是:a、b、EventHandler委托对象都被系统回收了。