首先,爲了讓EXCEL.EXE進程退出,您不必顯式釋放所使用的所有COM對象。當您獲取對COM對象的另一個引用時,由.NET運行時隱式爲您創建的運行時可調用包裝程序(RCW)由GC收集,這將釋放基礎COM對象。
您所要做的就是調用Quit方法,釋放RCWs引用並讓GC收集它們。
//This runs the EXCEL.EXE process.
Microsoft.Office.Interop.Excel.Application app =
new Microsoft.Office.Interop.Excel.Application();
//This locks the excel file either for reading or writing
//depending on parameters.
Microsoft.Office.Interop.Excel.Workbook book = app.Workbooks.Open(...);
...
//Explicitly closing the book is a good thing. EXCEL.EXE is alive
//but the excel file gets released.
book.Close();
//This lets the EXCEL.EXE quit after you release all your references to RCWs
//and let GC collect them and thus release the underlying COM objects.
//EXCEL.EXE does not close immediately after this though.
app.Quit();
app = null;
二,如果你離開所謂的雙點代碼行,你不會造成任何內存泄漏。垃圾收集器將收集RCW並在某個時候釋放COM對象,即當它找到它時。
最後,如果您希望顯式地釋放RCW和相應的COM對象以最大限度地減少內存壓力,可以在釋放引用之後顯式調用GC來收集RCW,甚至顯式釋放底層COM對象在GC收集RCW之前。但要小心。這最後一種方式會讓您承擔在此之後從未使用剩餘的RCW或者您將有例外的情況。
using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
Application app = new Application();
Workbooks books = clsExcelApplication.Workbooks;
Workbook book = books.Open("...");
Sheets sheets = book.Sheets;
Worksheet sheet = sheets["..."];
...
//Trying to be as explicit as we can.
book.Сlose();
//Revese order. Using FinalReleaseComObject is even more dangerous.
//You might release an object used inside excel
//code which might lead to some dreadful internal exceptions.
int remainingRefCount;
remainingRefCount = Marshal.ReleaseComObject(sheet);
remainingRefCount = Marshal.ReleaseComObject(sheets);
remainingRefCount = Marshal.ReleaseComObject(book);
remainingRefCount = Marshal.ReleaseComObject(books);
app.Quit();
remainingRefCount = Marshal.ReleaseComObject(app);
請記住。如果你手動釋放COM引用超過EXCEL.EXE一輩子不依賴於的RCW,當你喜歡,你可以抵消他們...
sheet = null;
sheets = null;
book = null;
books = null;
app = null;
在最明確的情況下,不要忘記檢查從返回Marshal.ReleaseComObject的。如果它不是零,除了剛剛發佈的RCW之外,其他人都持有對基礎COM對象的COM引用。
我發現只要你確定你關閉了你處理的所有東西併發布excelapp.Quit它確實去了 - 我發現了一些premade exporttoexcel代碼中的一些問題,但是在最後設置excelapp = null時,這個確保沒有東西掛在任何東西上 – BugFinder
GC不會釋放COM組件。你必須明確地做到這一點。 – Enigmativity
@Enigmativity GC不發佈通過某些API獲取的純COM對象,但它釋放通過Runtime Callable Wrappers獲得的COM對象。在excel的情況下,它確實釋放它們。 –