有一些示例代码:
public class Publisher
event Published()
end class
public class Subscriber
public sub new(Publisher as Publisher)
addhandler Publisher.Published,
sub()
end sub
end sub
end class
即使将未捕获的空lambda函数作为事件处理程序传递,Publisher
在Subscriber
构造函数中注册该事件是否也可以防止Subscriber
垃圾回收Subscriber
?
在C#中是否一样?
编辑
一个简单的控制台应用程序对其进行测试:
Sub Main()
Dim Publisher As New Publisher
For i = 1 To 1000000
Dim Subscriber As New Subscriber(Publisher)
Next
GC.Collect()
Dim TotalMemory = GC.GetTotalMemory(True)
Trace.WriteLine(TotalMemory)
End Sub
不幸的是,垃圾回收后,该应用程序消耗了36 MB的内存,这意味着所有订阅服务器都保留在内存中!
在不同的目标框架2.0、3.0、3.5、4.0、4.5上进行调试和发布会得到相同的结果。
如果您在匿名函数中未引用任何与Subscriber相关的内容,则它将被编译为Subscriber类的静态方法,因此,它不会阻止垃圾回收Subscriber类的任何实例。您可能需要查看此链接-http://blogs.msdn.com/b/oldnewthing/archive/2006/08/02/686456.aspx-了解更多信息。
更新。下面的代码显示了在Release模式下运行时总内存的几乎相同的值(在Debug模式下,确实如您所说的那样工作):
internal class Program {
private static void Main(string[] args) {
Console.WriteLine("Before: {0}", GC.GetTotalMemory(true));
var pub = new Publisher();
for (int i = 0; i < 1000000; i++) {
var sub = new Subscriber(pub);
}
GC.Collect();
Console.WriteLine("After: {0}", GC.GetTotalMemory(true));
Console.ReadKey();
}
}
public class Publisher {
public EventHandler Published;
}
public class Subscriber {
public Subscriber(Publisher pub) {
pub.Published += delegate { };
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句