2010-03-15 356 views
9

什麼是破壞在C#中的Excel COM互操作對象的方法,除了這些:如何銷燬C#中的COM對象?

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

請建議僅內置技術,而不是其他工具,如bigcannon等

+2

爲什麼你需要 - 在大多數情況下,框架應該爲你照顧這個? – Paddy 2010-03-15 16:38:09

+3

object_instance = null;順便不摧毀對象。它甚至不確保它會被垃圾收集(即,因爲別的東西仍然可以引用它) – 2010-03-15 16:41:18

+0

我遇到了問題,我的excel程序中未刪除的對象導致正常,你可以說「閃爍」,搜索後一個字符串 – perilbrain 2010-03-15 16:50:32

回答

17

拋磚引玉的是,如果你沒有刪除對象的所有引用,即使GC.Collect也不會銷燬它。

C#(或.NET通常)中的規則是你不能破壞一個對象。 Dispose()不會這樣做。終結者不會這樣做(規則2,除非你知道爲什麼需要它,並且不要直接調用它),否則不要使用終結器。

對於.NET,這些都是你需要做的事情:

  1. 如果對象持有非託管對象的引用,實現IDispose模式。並充分實施;它不僅僅是提供Dispose()方法。
  2. 有一個終結器的唯一原因是釋放非託管對象,並只有在您的對象沒有妥善處理的情況下。一旦調用了dispose方法,它應該執行清理,然後通過調用GC.SuppressFinalize來「終止」終結器。
  3. 如果您正在使用實現Dispose()方法的對象,請在完成該對象時調用Dispose()。最佳做法是使用使用塊分配該對象。從使用塊中退出將自動調用Dispose()。
  4. 當您完成對象時,請刪除對象的所有引用,包括事件處理程序,委託等。
  5. 除此之外,請相信垃圾回收器完成其工作。不要惹垃圾收集器;你只會讓事情變得更糟,除非你真的真的知道你在做什麼以及爲什麼。
+0

+1 - 很好的答案!我有資格#1包括資源。如果您的類持有對實現IDispose的託管對象的引用,則還需要實現Dispose Pattern。一般而言,一次性課程將代表有限或昂貴的外部資源。 – TrueWill 2010-03-15 17:13:50

+0

@TrueWill,很好的建議。謝謝。 – 2010-03-15 17:21:31

+0

Marshal.ReleaseComObject呢? – 2010-03-18 17:45:25

15

垃圾收集器是唯一的機制這可以銷燬一個受管對象,但通常不會顯式調用它。你只是讓它做它的事情。

就像你從來沒有把自己的垃圾帶到車庫一樣,你只是把它放在角落裏。這總是垃圾人的責任。

您可以釋放對事物的引用並使用IDisposable,終結器和析構函數清理它們,但不會將它們銷燬。

通過使用System.GC,你可以讓垃圾人早點做事 - 爲你自己請求一個自定義的運行 - 但這通常會搞亂他的日程安排,並且他還有更多的垃圾可以處理,而不僅僅是你的垃圾,所以它是不建議。

+0

(整理了界面名稱 - 希望你不介意) – 2010-03-15 16:39:33

+0

完全沒有,但我是中間編輯,意外地摧毀了它,但把它放回去了。 – 2010-03-15 16:40:54

+0

有幾個賭場,你需要明確刪除對象.......雖然我不能夠顯示你我的程序,但可以向你保證,我真的需要銷燬對象..「 – perilbrain 2010-03-15 16:43:04

0

如果您的對象分配了大量資源,最好實現IDisposable並顯式調用Dispose。如果由於某些原因無法調用Dispose並且您的課程預留了非託管內存,那麼您可以使用GC.AddMemoryPressure(在終結器中使用與GC.RemoveMemoryPressure相匹配的)來告訴GC您的課程比看起來更重,優先考慮其優先級清理。

2

大多數情況下,您必須刪除對象的所有引用。只有這樣垃圾收集器才能看到它並將其銷燬。

注意這一點:

object_instance = null; 

這一切確實是殺object_instance參考。這是唯一的參考。如果有其他參考,則不會收集。

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

...

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

如果你真的需要明確地釋放由對象佔用的內存,並且你確信你會選擇那一刻滅掉它比GC好,那麼只有合理的選擇是將它分配到堆棧上,並在從分配方法返回時讓它死亡。