首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

關於 C# 呼叫 Excel 的資源佔用問題

     編輯:關於C語言

看了農民伯伯的《C# 操作 Excel 之旁門左道 [ C# | Excel ]》以後,無意中想起 2 年前做的一個小專案,自己也遇到過 Excel 的進程無法結束掉的這種怪問題,最終還是解決了,其實解決的原理很簡單,Excel 是一個很特殊的東西,所有對它的操作都是獨佔的,因此就有必要在資源釋放上嚴格進行。為了更好的跟大家交流,也同時幫助那些正在被困惑的程式設計師朋友們,下面就附上我以前的一段小程式碼,為了能夠更快更容易說明問題,程式碼經過了刪減,只保存了結構的完整性,但不保證能夠順利編譯通過,程式碼如下:

需要引用的命名空間

using Excel = Microsoft.Office.Interop.Excel;
try
{
    Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
    Microsoft.Office.Interop.Excel.Workbook workbook = Excel.Workbooks.Open(lujing2, System.Type.Missing, false, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing);
    Excel.Visible = true;
    Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item(1);
    // 開始執行 Excel 操作

    if (Excel.ActiveWorkbook.Saved == false)
    {
        Excel.ActiveWorkbook.Save();
    }
    Excel.Quit();
    Excel = null;
    Application.Exit();
    GC.Collect(System.GC.GetGeneration(worksheet));
    GC.Collect(System.GC.GetGeneration(workbook));
    GC.Collect(System.GC.GetGeneration(Excel));
}
catch
{
}
finally
{
    GC.Collect();
}

同時,這裡有一個比較有爭議的問題,我特此聲明下:微軟強烈建議不要透過 GC.Collect 方法來強制執行垃圾回收,因為那會妨礙 GC 本身的工作方式。只有在明確知道有大量物件停止參考時,才考慮使用 GC.Collect 方法來呼叫收集器。

微軟針對 Excel 提供的 COM 還是非常不錯的,還請朋友們不要錯怪於它。

關於網友的回復的補充:

Excel 是否是受控資源,根本就扯不上,我覺得這是不同層面的東西,關鍵是我們的程式是透過呼叫 COM 來對 Excel 進行操作的,我們的 COM 應該不是非受控資源吧。

再舉個例子:Web 中常見的檔案上傳與檔案打包下載,這些檔案是受控資源還是非受控資源,其實什麼都算不上,更談不到什麼釋放與不釋放的問題了。

我們的程式呼叫 COM,COM 去和 Excel 執行操作,按照正常的程式碼規範,這些都是可以正常被釋放的。

使用 kill 掉的程式,就像 Excel 被突然結束掉,可能會產生碎片等等,嚴重的 Excel 還會被損壞,更有甚者,Excel 的進程根本就 kill 不掉,反倒會讓你的程式產生異常,造成根本無法預料到的損失。

再比如說,COM 做了些什麼工作,就像正常的使用者打開一個 Excel,執行了些操作,然後把 Excel 關閉了,我們不需要再讓第三方軟體去執行什麼記憶體的釋放工作。

不同層面的東西,不要放一塊,否則會把自己都搞得很亂。

不知道我講的夠不夠清楚,還是我本身理解的有問題,歡迎指出,我們一起探討。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved