我想对GCHandle.Alloc(Object)的契约有一个严格的理解。

我从文档中了解到,如果我打电话:

GCHandle gc = GCHandle.Alloc(foo);

foo 将保证不会被垃圾收集,直到我调用:
gc.Free();

我也明白,如果 AppDomain 被卸载,foo 将被收集。

我想检查的是,在没有调用 Free 的情况下调用 Alloc 是否与根引用有效相同(在 GC 眼中)。

需要明确的是,如果这是真的,那么 GCHandle 变量 gc 的范围对 foo 的生命周期没有影响。如果 Free 未被调用,则 foo 会一直存在,直到 AppDomain 卸载。

例如。
一个对象对自身调用 Alloc 并且不保留 GCHandle 实例,它会一直存在,直到 AppDomain 被卸载。

这样对吗?

一些引用:

http://msdn.microsoft.com/en-us/library/a95009h1.aspx

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.free.aspx

http://blogs.msdn.com/b/clyon/archive/2005/03/18/398795.aspx

最佳答案

正确的。 GCHandle 变量对传递给 GCHandle.Alloc() 的对象的生命周期没有影响。我用以下两个类验证了这一点:

class Test
{
   public Test ()
   {
      System.Runtime.InteropServices.GCHandle.Alloc(this);
   }
   ~Test ()
   {
   }
}
class Server : MarshalByRefObject
{
   public Server ()
   {
      new Test();
   }
   public void Collect ()
   {
      GC.Collect();
      GC.WaitForPendingFinalizers();
   }
}

以及以下测试代码:
AppDomain ad = AppDomain.CreateDomain("test");
Server svr = (Server)ad.CreateInstanceAndUnwrap(
   System.Reflection.Assembly.GetExecutingAssembly().FullName,
   typeof(Server).FullName);
for (Int32 i = 0; i < 100; i++)
   svr.Collect();

使用此示例,如果您在 Test 类的终结器中设置断点,您会注意到在任何 GC.Collect/WaitForPendingFinalizers 调用期间都不会调用它。但是,当卸载 appdomain 时会命中断点。

关于.net - GCHandle.Alloc(Object) 的契约究竟是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7688287/

10-14 00:06