2016-11-14 107 views
3

公司將在公佈的情況下,所有非託管COM對象,如果我用這樣的代碼重要事項沒有分配給var的COM對象沒有被釋放嗎?

var worksheet = new Application().Workbooks.Add().Worksheets.Add(); 
Marshal.ReleaseComObject(worksheet); 

,而不是像這樣的代碼

var excel = new Application(); 
var workbook = excel.Workbooks.Add(); 
var worksheet = workbook.Worksheets.Add(); 
Marshal.ReleaseComObject(excel); 
Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(worksheet); 

如果有一些文件請發送鏈接回答。

+0

也許使用FinalReleaseComObject? https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject(v=vs.110).aspx – EJoshuaS

+4

這兩個都不夠好。永遠不要編寫手動內存管理代碼,你會錯誤的,並沒有機會去調試它。 http://stackoverflow.com/a/25135685/17034。 –

+0

FinalReleaseComObject仍然只釋放對特定COM對象的引用,而不是所有對所有COM對象的引用。 –

回答

1

實際上,這兩個代碼示例都會讓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()); 
+1

其實我需要保持Excel運行,直到它將被用戶交互關閉。 –

+1

@ Uzivatel828你的意思是用戶與你的程序交互?如果是這樣,那麼你不想再釋放應用程序對象 - 當你想要關閉它時,你需要使用Save和Quit來完成所有的事情。 – EJoshuaS

+0

當Excel關閉時,程序仍然會及時運行,因此所有引用都應該在下班後立即釋放。 –