使用OleDbConnection的Open方法时,C#Excel不会自行关闭

时间:2012-01-03 10:02:25

标签: c# excel oledb

我正在创建和发布对excel com接口的引用来操作excel的工作表。

在这种情况下,Excel正确关闭。 如果我使用OleDbDataAdapter连接来获取数据,那么excel仍然在内存中。

我已经阅读了关于这个主题的几乎所有内容。

  1. 我已经为适当的发布引用创建了子例程。
  2. 我正在使用:
  3. GC.Collect();
    GC.WaitForPendingFinalizers();
    

    我还能做什么?

    这似乎是一个不起眼的问题..

    以下是代码:

    namespace ExcelTestCode
    {
     class Program
     {
       static void Main(string[] args)
       {
         Application excel = null;
         Workbook workbook = null;
         Worksheet workSheet = null;
         object oMissing = Missing.Value;
    
         excel = new Application { Visible = false };
         workbook = excel.Workbooks.Open(@"c:\temp.xls", 0, false, 5, "", "", 
                    true, XlPlatform.xlWindows, "\t", false, false, 0, true, true, oMissing);
         workSheet = (Worksheet)workbook.Sheets[1];
    
         try
         {
           string strError = "";
           System.Data.DataTable dtTable = null;
    
           //If I remove the following line, everything is allright
           dtTable = ImportDataTableFromExcelIMEX(@"c:\temp.xls", out strError);
         }
         finally
         {
           if (workSheet != null)
           {
             Marshal.ReleaseComObject(workSheet);
             workSheet = null;
           }
           if (workbook != null)
           {
             workbook.Close(false, oMissing, oMissing);
             Marshal.ReleaseComObject(workbook);
             workbook = null;
           }
    
           if (excel != null)
           {
             excel.Quit();
             Marshal.ReleaseComObject(excel);
             excel = null;
           }
           GC.Collect();
           GC.WaitForPendingFinalizers();
           GC.Collect(); 
         }
       }
    
       public static System.Data.DataTable ImportDataTableFromExcelIMEX(string filename, out string error)
       {
         string connstring = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + @";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""";
         OleDbConnection upocn = new OleDbConnection(connstring);
         try
         {
           upocn.Open();
    
           System.Data.DataTable dt = null;
           dt = upocn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
    
           using (OleDbDataAdapter upoda = new OleDbDataAdapter("select * from [" + dt.Rows[0]["TABLE_NAME"].ToString() + "]", upocn))
           {
             DataSet upods = new DataSet();
             error = string.Empty;
    
             upoda.Fill(upods);
    
             if (!string.IsNullOrEmpty(error))
               return null;
    
             return upods.Tables[0];
           }
         }
         catch (Exception ex)
         {
           error = ex.Message;
         }
         finally
         {
           upocn.Close();
           upocn = null;
         }
         return null;
       }
     }
    }
    

2 个答案:

答案 0 :(得分:2)

尝试使用(OleDbConnection upocn = new OleDbConnection(connectionString)),或调用upocn.Dispose()

来自MSDN OleDbConnection.Dispose :释放System.ComponentModel.Component使用的所有资源。 OleDbConnection.close :关闭与数据源的连接

已更新如果我像上面的代码一样执行connection.close,我可以产生此问题,但是当我调用dispose它工作正常时,我没有看到任何excel实例。以下是适合我的代码。确保在测试之前从任务管理器清除运行实例

class Program
{
    static void Main(string[] args)
    {
        Application excel = null;
        Workbook workbook = null;
        Worksheet workSheet = null;
        object oMissing = Missing.Value;

        excel = new Application { Visible = false };
        workbook = excel.Workbooks.Open(@"c:\Book1.xls", 0, false, 5, "", "",
                   true, XlPlatform.xlWindows, "\t", false, false, 0, true, true, oMissing);
        workSheet = (Worksheet)workbook.Sheets[1];

        try
        {
            string strError = "";
            System.Data.DataTable dtTable = null;

            //If I remove the following line, everything is allright 
            dtTable = ImportDataTableFromExcelIMEX(@"c:\Book1.xls", out strError);
        }
        finally
        {
            if (workSheet != null)
            {
                Marshal.ReleaseComObject(workSheet);
                workSheet = null;
            }
            if (workbook != null)
            {
                workbook.Close(false, oMissing, oMissing);
                Marshal.ReleaseComObject(workbook);
                workbook = null;
            }

            if (excel != null)
            {
                excel.Quit();                   
                Marshal.ReleaseComObject(excel);
                excel = null;
            }
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }
    }

    public static System.Data.DataTable ImportDataTableFromExcelIMEX(string filename, out string error)
    {
        string connstring = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + @";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""";

        try
        {
            using (OleDbConnection upocn = new OleDbConnection(connstring))
            {
                upocn.Open();
                System.Data.DataTable dt = null;
                dt = upocn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                using (OleDbDataAdapter upoda = new OleDbDataAdapter("select * from [" + dt.Rows[0]["TABLE_NAME"].ToString() + "]", upocn))
                {
                    DataSet upods = new DataSet();
                    error = string.Empty;

                    upoda.Fill(upods);

                    if (!string.IsNullOrEmpty(error))
                        return null;

                    return upods.Tables[0];
                }
            }
        }
        catch (Exception ex)
        {
            error = ex.Message;
        }

        return null;
    }
}

答案 1 :(得分:1)

我遇到了同样的问题。基本上我不得不把

    finally
{
    if (xlCmd != null)
    {
        xlCmd.Dispose();
        xlCmd = null;
    }
}

在初始化新的OleDBCommand xlCmd和

之前
    finally
{
    if (xlCon != null)
        xlCon.Dispose();
}

告诉OleDBConnection xlCon关闭。确保您还使用如下所示的使用块初始化您的Excel连接:

    using (OleDbConnection xlCon = new OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0; " +
    "Data Source = " + xlFile + ";Mode=ReadWrite;" +
    "Extended Properties='Excel 12.0;HDR=YES;'"))   //Automatically creates a new excel file (Do not include IMEX=1)
{

如果您想在应用程序运行时打开文件并完成导出,则需要进行这些手动清理。