2012-10-02 42 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(); –