簡體   English   中英

我應該如何聲明一個Microsoft.Office.Interop.Excel.Worksheet,以便可以在C#中將其關閉?

[英]How should I declare a Microsoft.Office.Interop.Excel.Worksheet so I can close it in C#?

我很難確保我的COM對象正在關閉,因此我不會在后台運行EXCEL.EXE進程。 我了解到,聲明的雙點和鏈接不好,因為這可能會使COM對象無處不在。

有誰知道如何解決這一行代碼,以便我可以正確關閉並釋放工作表COM對象?

worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[strName];

編輯:當我完成執行此行以關閉打開的Excel對象時,我嘗試使用app.Quit(),但是這不起作用。 但是,如果我在此行之前調用app.Quit(),它將起作用。

首先,為了退出EXCEL.EXE進程,您不必顯式釋放您使用的所有COM對象。 當您獲得對COM對象的另一個引用時,.NET運行時為您隱式創建的運行時可調用包裝(RCW)由GC收集,這將釋放基礎COM對象。

您所需要做的就是調用Quit方法,釋放RCW引用並讓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引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM