2012-08-05 42 views
2

我使用一些對象,如工作簿,工作表,應用程序用於Excel任務。在完成Excel之後,我嘗試通過下面的代碼發佈它們。畢竟,我仍然可以在任務管理器中看到EXCEL.EXE。爲什麼它不完全釋放?如何發佈爲Excel創建的對象(C#)

我爲Excel任務等級:

Excel._Application app = new Excel.Application(); 
Excel._Workbook workbook = app.Workbooks.Add(Type.Missing); 
Excel._Worksheet worksheet = null; 
app.Visible = true; 

worksheet.Cells[1, 1] = "test string"; 

workbook.SaveAs("C:\testfile.xlsx"); 

object misValue = System.Reflection.Missing.Value; 
workbook.Close(true, misValue, misValue); 
app.Quit(); 

releaseObject(worksheet2); 
releaseObject(workbook); 
releaseObject(app); 

releaseObject類:

private void releaseObject(object obj) 
    { 
     try 
     { 
      System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 
      obj = null; 
     } 
     catch (Exception ex) 
     { 
      obj = null; 
      MessageBox.Show("Unable to release the Object " + ex.ToString()); 
     } 
     finally 
     { 
      GC.Collect(); 
     } 
    } 

EXCEL.EXE仍處於任務管理器: enter image description here

+1

你可以嘗試也設置'app','workbook'和'worksheet'爲' null'向GC表明不再需要對這些對象的引用。 – 2012-08-05 23:04:09

+1

'Excel._Worksheet worksheet = null;'和一個名爲'worksheet'的對象的後續用法不匹配到'releaseObject(worksheet2);'但這可能只是一個錯字,而不是原始代碼 – barrowc 2012-08-05 23:26:43

+0

@barrowc已經擊中了頭部。我懷疑這是一個錯字。我使用相同的'releaseObject(object obj)',從來沒有問題.... – 2012-08-06 00:15:29

回答

4

已經回答見:

How do I properly clean up Excel interop objects?

基本上COM對象是非託管對象(duh),並且在超出範圍時不會被釋放。 System.Runtime.InteropServices.Marshal.ReleaseComObject()可用於在它們完成之前(在垃圾回收器中)釋放它們,但是您必須確保保留所有對象的引用: excelApp.Worksheets.Open ()創建兩個對象:使用Open()方法打開的集合「工作表」和「工作表」。

0

您將n EED做這樣的,因爲它關閉Excel應用程序打開在後臺的Excel程序....

app .Application.Quit(); 

在代碼中添加上面一行代碼方式如下:

object misValue = System.Reflection.Missing.Value; 
    workbook.Close(true, misValue, misValue); 
    app .Application.Quit(); 
    app.Quit(); 
+0

沒有工作:(我已經嘗試了幾次 – Ned 2012-08-06 02:35:25

1

這是一個而因爲我已經完成了Office Interop(我實際上是使用它的Outlook,但概念應該是相同的)。我能完全釋放一切的唯一途徑是做到這一點:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

給它一個鏡頭....

+0

+1我正在等待這個答案,但試試這個大小http://stackoverflow.com/questions/3829928/under-what-c​​ircumstances-we-需要撥打電話gc-collect-twice – 2012-08-06 01:40:41

+0

這似乎是個好主意,但不起作用,不幸的是, – Ned 2012-08-06 02:35:58

1

這是一個我無法解決的問題。我以前見過所有這些答案,並且我已經實現了所有這些答案,並且仍然沒有關閉。我必須用蠻力來做事情。我所做的是創建了一個BAT文件並從我的程序中運行它。這裏是文件的內容:

Taskkill /F /IM excel.exe 

這將調用所有你的excels運行。如果你不能找出不同的解決方案,我會用這個。

2

它非常容易使用過程中殺死從任務管理器中的Excel對象,請參見下面&享受..

//Kill the all EXCEL obj from the Task Manager(Process) 
System.Diagnostics.Process[] objProcess = System.Diagnostics.Process.GetProcessesByName("EXCEL"); 

if (objProcess.Length > 0) 
{ 
    System.Collections.Hashtable objHashtable = new System.Collections.Hashtable(); 

    // check to kill the right process 
    foreach (System.Diagnostics.Process processInExcel in objProcess) 
    { 
     if (objHashtable.ContainsKey(processInExcel.Id) == false) 
     { 
      processInExcel.Kill(); 
     } 
    } 
    objProcess = null; 
} 

//In case of you want to quit what you have created the Excel object from your application //just use below condition in above, 

    if(processInExcel.MainWindowTitle.ToString()== "")