简体   繁体   English

如何在C#中销毁COM对象?

[英]How can I destroy COM objects in C#?

What are the methods to destroy Excel COM Interop objects in C#, besides these: 除了这些之外,在C#中销毁Excel COM Interop对象的方法有哪些:

object_instance = null;
System.GC.collect();
&
System.Runtime.InteropServices.Marshal.ReleaseComObject(object);

Please suggest only inbuilt techniques, not other tools like bigcannon, etc. 请建议只使用内置技术,而不是像bigcannon等其他工具。

The kicker is that if you haven't dropped all references to the object, even GC.Collect won't destroy it. 踢球者是如果你没有删除对象的所有引用,即使GC.Collect也不会销毁它。

The rule in C# (or .NET generally) is that you can't destory an object. C#(或通常是.NET)中的规则是您不能破坏对象。 Dispose() won't do it. Dispose()不会这样做。 A finalizer won't do it (rule number 2, don't use a finalizer unless you know why you need it, and don't ever call it directly). 终结者不会这样做(规则2,除非你知道为什么需要它,否则不要使用终结器,也不要直接调用它)。

For .NET, these are the things you need to do: 对于.NET,这些是您需要做的事情:

  1. If an object holds references to unmanaged objects, implement IDispose pattern. 如果对象包含对非托管对象的引用,请实现IDispose模式。 And implement it fully; 并充分实施; it's more than just providing a Dispose() method. 它不仅仅是提供Dispose()方法。
  2. The only reason to have a finalizer is to release unmanaged objects, and only in the event that your object hasn't been properly disposed. 拥有终结器的唯一原因是释放非托管对象,并且仅在您的对象未正确处理的情况下。 Once your dispose method is called, it should do the cleanup, then "kill" the finalizer by calling GC.SuppressFinalize. 一旦调用了dispose方法,它就应该进行清理,然后通过调用GC.SuppressFinalize来“终止”终结器。
  3. If you are using an object that implements a Dispose() method, call Dispose() when you're done with that object. 如果您正在使用实现Dispose()方法的对象,请在完成该对象后调用Dispose()。 Best practices is to allocate that object with a using block. 最佳实践是使用using块分配该对象。 Exit from the using block will call Dispose() automatically. 从using块退出将自动调用Dispose()。
  4. When you are done with an object, drop all references to the object, including event handlers, delegates, etc. 完成对象后,删除对象的所有引用,包括事件处理程序,委托等。
  5. Beyond that, trust the garbage collector to do its job. 除此之外,相信垃圾收集器可以完成它的工作。 Don't mess with the garbage collector; 不要乱搞垃圾收集器; you're only likely to make things worse, unless you really, really, really know what you're doing and why. 你只会把事情变得更糟,除非你真的,真的,真的知道你在做什么以及为什么。

The garbage collector is the only mechanism that can destroy a managed object , but you usually don't invoke it explicitly. 垃圾收集器是唯一可以销毁托管对象的机制,但通常不会显式调用它。 You just let it do its thing. 你只是让它做它的事情。

Just like you never take your own trash to the depot, you just leave it sitting on the corner. 就像你从不把自己的垃圾带到车厂一样,你只需将它留在角落里。 It's always the garbage man's responsibility. 这总是垃圾人的责任。

You can release references to things and clean them up with IDisposable, finalizers and destructors but not destroy them. 您可以释放对事物的引用并使用IDisposable,终结器和析构函数清理它们,但不要销毁它们。

By using System.GC you can ask the garbage man to do things early - request a custom run just for yourself - but this usually screws up his schedule and he has a lot more trash to deal with than just yours so it's not recommended. 通过使用System.GC,您可以要求垃圾人尽早做事 - 只为自己请求自定义运行 - 但这通常搞砸了他的日程安排,他有更多的垃圾要处理,而不仅仅是你的,所以不推荐。

For the most part, you have to remove all references to an object. 在大多数情况下,您必须删除对对象的所有引用。 Only then will the garbage collector see it and destroy it. 只有这样,垃圾收集器才会看到它并将其销毁。

Be aware of this: 请注意这一点:

object_instance = null;

All this does is kill the object_instance reference. 所有这一切都是杀死object_instance引用。 This works if it's the only reference. 如果它是唯一的参考,这是有效的。 If there are other references, then it won't be collected. 如果有其他参考,则不会收集。

var skywalker = new Person();
var object_instance = skywalker;

... ...

object_instance = null;
//It's still alive and won't be collected because skywalker lives...

If your object allocates significant resources, it's best to implement IDisposable and explicitly call Dispose. 如果您的对象分配了大量资源,最好实现IDisposable并显式调用Dispose。 If you can't call Dispose for some reason and your class reserves unmanaged memory, you can use GC.AddMemoryPressure (with a matching GC.RemoveMemoryPressure in the finalizer) to tell the GC your class is heavier than it looks, prioritizing it for earlier cleanup. 如果由于某种原因无法调用Dispose,并且您的类保留了非托管内存,则可以使用GC.AddMemoryPressure(在终结器中使用匹配的GC.RemoveMemoryPressure)告诉GC您的类比它看起来更重,优先级更早清理。

如果你真的需要明确释放一个对象所占用的内存,并且你确定你会选择比GC更好地消除它的那一刻,那么唯一合理的选择就是在堆栈上分配它并让它在你返回时死掉分配它的方法。

If you want control so that you can manage resources of the object, then implement the IDisposable interface. 如果您想要控制以便可以管理对象的资源,那么实现IDisposable接口。

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

If resources are not the reason why you want to explicitly control object destruction, I can't fathom why you want that level of control... Do you use object pooling? 如果资源不是您想要显式控制对象销毁的原因,我无法理解为什么您需要这种级别的控制...您是否使用对象池?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM