2010-06-22 88 views
1

我們在我們的代碼中的許多地方使用Excel互操作,但是我有一個函數似乎並沒有關閉它使用的Excel過程..我簡化了代碼下來,它似乎只要我在這個功能打開一個工作簿,它保持四處閒逛。我已經包含了下面的代碼,我確保每個對象都被定義,發佈和清零,但Excel仍在運行。C#.net Excel Interop離開Excel過程掛

 System.Data.DataTable dtExcelSheet = new System.Data.DataTable(); 
     Microsoft.Office.Interop.Excel.Application excelObject = new Microsoft.Office.Interop.Excel.Application(); 

     dtExcelSheet.Columns.Add("SheetName", typeof(string)); 
     dtExcelSheet.Columns["SheetName"].ReadOnly = false; 
     dtExcelSheet.Columns["SheetName"].Caption = "Sheet Name"; 


     Workbooks wbs = excelObject.Workbooks; 

     Workbook excelWorkbook = wbs.Add(excelFile); 

     excelWorkbook.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value); 
     wbs.Close(); 
     excelObject.Quit(); 

     int i1 = Marshal.FinalReleaseComObject(excelWorkbook); 
     int i2 = Marshal.FinalReleaseComObject(wbs); 
     int i3 = Marshal.FinalReleaseComObject(excelObject); 


     excelWorkbook = null; 
     wbs = null; 
     excelObject = null; 

     GC.GetTotalMemory(false); 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     GC.Collect(); 
     GC.GetTotalMemory(true);  

回答

1

請確保您沒有在後臺線程上調用Excel。我有一個類似的問題,我正在清理所有的COM對象,但Excel仍然沒有死去,結果是問題所在。

我寫下了我的經驗和解決方案here

1

完整的猜測,但確實該行:

dtExcelSheet.Columns.Add("SheetName", typeof(string)); 

返回所創建的列?

如果是這樣的話,您可能需要存儲該參考文件並在最後清理該參考文件。

編輯:此外,我不認爲你應該設置變量爲null在最後,我認爲只是再次訪問它們。

你不應該告訴GC收集等,但我認爲這可能是你的測試代碼。

+0

匿名專欄也是我的猜測。 – Mathias 2010-06-23 05:21:10

+0

這是一個數據表中的列,沒有連接到Excel表格.... – 2010-06-25 13:27:07

+0

@瑞克:你說的對,我誤解了。我的答案剩下的唯一一件事就是在最後不要將它們設置爲null,儘管這聽起來毫無意義,但值得嘗試。 – 2010-06-25 14:23:49

1

這段時間以來我一直在討論這個問題,所以沒有什麼會跳出來。

我在這些情況下通常的建議是將您的Excel應用程序對象設置爲Visible = true,看看是否沒有對話框彈出。無論你做什麼,Excel/Word有時會拒絕關閉,如果他們認爲有一個模式對話框打開。無論如何,這是首先要檢查的東西。

+1

如果發生這種情況,您只需設置DisplayAlerts = false即可 – Jess 2010-06-22 21:17:07

1

我試着運行你的代碼,但是我不能重現這個問題。如果我使用調試器對其進行檢查,Excel進程會在最後一次調用FinalReleaseComObject後終止。罪魁禍首可能在於某些代碼不在您的列表中?

使用COM互操作時,我發現以非常微妙的方式增加COM對象的引用計數是非常容易的。例如,假設你做這樣的事情:

excelWorkbook.Foo.Bar(); 

這可以遞增Foo對象的引用計數,讓你與它釋放之後......並留下Excel進程徘徊在你之前沒有辦法關閉你的應用程序。您可以重新編寫代碼這樣上面的一行:

Foo foo = excelWorkbook.Foo; 
foo.Bar(); 
Marshal.ReleaseComObject(foo); 

這並不漂亮,但它會遞減Foo對象的引用計數,你正在使用它完成之後。

0

前幾天發生了同樣的事情。在Excel Automation上看到我的問題,關於修復(問題主要涉及多行刪除,但我也遇到同樣的問題,因爲它與正確釋放所有COM對象有關)。