我已经阅读了很多文章关于释放RCW的安全网,并在我看来,没有人能对需要什么样的顺序做什么同意,所以我要求你们为你们的意见。例如,一个可以这样做:

object target = null;
try {
    // Instantiate and use the target object.
    // Assume we know what we are doing: the contents of this try block
    // do in fact represent the entire desired lifetime of the COM object,
    // and we are releasing all RCWs in reverse order of acquisition.
} finally {
    if(target != null) {
        Marshal.FinalReleaseComObject(target);
        target = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

不过,也有人主张做垃圾收集Marshal.FinalReleaseComObject之前,一些后,有的根本没有。真的有必要手动GC每一个RCW,它已经从它的COM对象分离尤其是在?

在我看来,它会更简单,更容易刚刚从COM对象分离的RCW和离开RCW自然到期:

object target = null;
try {
    // Same content as above.
} finally {
    if(target != null) {
        Marshal.FinalReleaseComObject(target);
    }
}

是否足以做到这一点?

有帮助吗?

解决方案

要具有参考公布目标COM对象,它是足够的和优选以只是调用Marshal.FinalReleaseComObject强制收集。换句话说,你见过你的责任,尽快释放你参考,你用它做。我不会碰FinalReleaseComObject的问题VS ReleaseComObject

这留下的,为什么人主张调用GC.Collect()WaitForPendingFinalizers()更大的问题?

由于一些设计中,这是很难知道什么时候有没有更多的托管引用,所以你不能安全地调用ReleaseComObject。你有两个选择,让内存建立和希望付费的发生或强制收集。 [查看评论史蒂芬强森羽绒投票注意事项】

这是附加说明的是,设置targetnull通常是不必要的,并且具体是在示例代码是不必要的。对象设置为Nothing是VB6常见的做法,因为它使用引用计数基于垃圾收集器。对于C#编译器足够聪明,甚至在离开之前范围(建设时释放)知道target是其最后一次使用后,可达,可GC'd。而到最后使用,我的意思是最后可能使用所以有在那里你可以将其设置为null案件。

:您可以通过下面的代码中看到自己这一点
   using System;
   class GCTest
   {
       ~GCTest() { Console.WriteLine("Finalized"); } 
       static void Main()
       {
           Console.WriteLine("hello");
           GCTest x = new GCTest();
           GC.Collect();
           GC.WaitForPendingFinalizers();
           Console.WriteLine("bye");
       }
   }

如果您构建释放(例如,CSC GCTest.cs),“结算”将打印出“你好”和“再见”之间。如果构建调试(例如,CSC /调试GCTest.cs),“结算”,将后“拜拜”,而设置x为空,以Collect()之前将有“固定”打印出。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top