實際上,這兩個代碼示例都會讓Excel進程在後臺運行。例如,您需要在應用程序對象上調用Application.Quit()
。以下作品:
private static void DoExcel()
{
var application = new Application();
var workbook = application.Workbooks.Add();
var worksheet = workbook.Worksheets.Add();
// Name that this will be saved as
string name = workbook.FullName + ".xlsx";
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), name);
// If a file of the same name exists, delete it so that we won't be prompted if
// we want to overwrite it when we save
if (File.Exists(fullPath))
File.Delete(fullPath);
// Save the workbook - otherwise we may be prompted as to whether we want to save when we go to quit
workbook.Save();
// Quit the application
application.Quit();
// Release the references
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(application);
// Release the .NET reference and run the garbage collector now to make sure the application is closed immediately
worksheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
其他一些好東西要記住:我這裏沒有使用它,但有一個Marshal.FinalReleaseComObject method這就是在這種情況下非常有用的。另外,我又沒有我的代碼示例中使用,但Marshal.ReleaseComObject
方法返回當前計數,所以你總是可以做在一個循環中釋放,如果你想確保計數達到零:
while (Marshal.ReleaseComObject(comObject) > 0) { }
您也可以將其用於調試目的 - 例如
int count = Marshal.ReleaseComObject(comObject);
Trace.TraceInformation("Current COM object reference count: " + count.ToString());
也許使用FinalReleaseComObject? https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject(v=vs.110).aspx – EJoshuaS
這兩個都不夠好。永遠不要編寫手動內存管理代碼,你會錯誤的,並沒有機會去調試它。 http://stackoverflow.com/a/25135685/17034。 –
FinalReleaseComObject仍然只釋放對特定COM對象的引用,而不是所有對所有COM對象的引用。 –