2012-10-02 73 views
1

我試圖打開一個xls文件,讀取多行數據,從數據形成自定義列表,然後關閉Excel表。這是我的:C#關閉excel句柄後讀取xls

InitializeWorkbook(Path); 
List<Custom> list = new List<Custom>(); 

Worksheet wkSht = (Worksheet)workBk.Worksheets[3]; 

if (wkSht.Name.Equals("Sht3", StringComparison.OrdinalIgnoreCase)) 
{ 
    Range PartNumRange = wkSht.get_Range("A:A", System.Reflection.Missing.Value); 
    Range RevRange = wkSht.get_Range("C:C", System.Reflection.Missing.Value); 
    Range SwRange = wkSht.get_Range("L:L", System.Reflection.Missing.Value); 
    Range NomenRange = wkSht.get_Range("M:M", System.Reflection.Missing.Value); 

    // Start at Row 6 
    int i = 6; 
    object Num = (PartNumRange[i, 1] as Range).Text; 
    object Nomen = (NomenRange[i, 1] as Range).Text; 
    object Sw = (SwRange[i, 1] as Range).Text; 
    object SwRev = (RevRange[i, 1] as Range).Text; 

    while (!string.IsNullOrEmpty(Num.ToString()) || !string.IsNullOrEmpty(Nomen.ToString()) || !string.IsNullOrEmpty(Sw.ToString()) || !string.IsNullOrEmpty(SwRev.ToString())) 
    { 
     if (!string.IsNullOrEmpty(Nomen.ToString()) && !string.IsNullOrEmpty(Sw.ToString()) && !string.IsNullOrEmpty(SwRev.ToString()) 
     { 
      Custom item = new Custom(); 

      item.PartNumber = (PartNumRange[i, 1] as Range).Text.ToString(); 
      item.Nomenclature = (NomenRange[i, 1] as Range).Text.ToString(); 
      item.SwNumber = (SwRange[i, 1] as Range).Text.ToString(); 
      item.SwRevision = (RevRange[i, 1] as Range).Text.ToString(); 

      list.Add(item); 
     } 

     i++; 
     Num = (PartNumRange[i, 1] as Range).Text; 
     Nomen = (NomenRange[i, 1] as Range).Text; 
     Sw = (SwRange[i, 1] as Range).Text; 
     SwRev = (RevRange[i, 1] as Range).Text; 
    } 

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

    Marshal.ReleaseComObject(PartNumRange); 
    Marshal.ReleaseComObject(RevRange); 
    Marshal.ReleaseComObject(SwRange); 
    Marshal.ReleaseComObject(NomenRange); 

    Marshal.ReleaseComObject(wkSht); 
    workBk.Close(false, System.Reflection.Missing.Value, false); 
    Marshal.ReleaseComObject(workBk); 

    Marshal.ReleaseComObject(ExcelWorkSheets); 

    ExcelApp.Quit(); 
    Marshal.ReleaseComObject(ExcelApp); 

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

我不知道爲什麼,但Excel完成後不關閉。只有在程序退出時Excel退出。我嘗試了各種各樣的組合,並且避免了兩點規則,但仍然是不成功的。關於我失蹤的任何想法?

編輯:調用ExcelApp.Quit關閉ExcelApp和ExcelWorksheets。

+0

相信我,我走了Excel自動化的方式(兩點法則,元帥釋放和所有),然後我發現了Flexcel,並且我從不回頭。你可以考慮這個解決方案? – Vinzz

回答

1

你可能想看看這篇文章:How do I properly clean up Excel interop objects?

有很多深入的討論有關在處理COM對象C#,你可能會發現有幫助。值得一讀。

+0

上面鏈接的問題非常好。事實上,答案可能存在相同的問題:workBk.Worksheets [3]圍繞工作表COM對象創建一個包裝。 –

+0

富有,就是這樣。還有一些我在API中使用過的API(包含InitializeWorkbook和CloseExcel方法)注意到了一些其他的東西來控制也在做同樣事情的Excel(比如ExcelApp.Workbook.Open()),所以我修復了這些現在一切正在開展。謝謝! – dangerisgo

0

您還需要密切呼籲

  • ExcelWorkSheets
  • ExcelApp

調用Marshal.ReleaseComObject的部署運行時可調用包裝,但保留應用程序本身還活蹦亂跳的。

+0

ExcelApp.Quit關閉了ExcelApp和ExcelWorkSheets,抱歉忘了提及這一點。 – dangerisgo

0

您可以使用此代碼嘗試 - 它的做工精細

while (Marshal.ReleaseComObject(YourRange) > 0) 
{} 

while (Marshal.ReleaseComObject(YourWorkSheet) > 0) 
{} 

while (Marshal.ReleaseComObject(YourWorkBook) > 0) 
{} 

YourApplication.quit() 

while (Marshal.ReleaseComObject(YourApplication) > 0) 
{} 
+0

我剛試過這個,它仍在運行。我已經更新了OP。 – dangerisgo

+0

@dangerisgo爲了清理所有實例而添加了代碼,我遇到了同樣的問題,我用while解決了;;;;;但是你可以刪除GC.Collect(); GC.WaitForPendingFinalizers(); –