1
using (OleDbCommand cmd = new OleDbCommand(cmdText, WFConn))
{
    int val = 0;

    AddParameterToODBComm(cmd, Type);
    AddParameterToODBComm(cmd, Year);

    try
    {
        WFConn.Open();
        OleDbDataReader reader = cmd.ExecuteReader();
        reader.Read();
        val = (int)reader[0];
    }
    catch (Exception ex) { MessageBox.Show(ex.Message); return 0; }
    finally { WFConn.Close(); }

    return (int)(val * ((int)numCount.Value * 0.01)); //Throws an InvalidComObjectException, but still works. 
}

此代码块完全按照我的意愿工作(返回记录集大小的 %),但每次运行时,我都会在最后一行进入调试器,但有COM object that has been separated from its underlying RCW cannot be used例外。

之前,return (int) etc etc 都在 try 块中,并且异常发生在 finally 块中的 Connection.Close() 上。

我在两个地方发生了同样的问题。问题是,如果我继续这个程序,一切都会完全按照预期进行。我已经在 SO 上检查了与此异常有关的其他问题,但它们指的是手动处置/释放 COM 对象,我在这里不打算这样做。

这里发生了什么,我只是没有看到?它肯定与关闭连接有关 - 我可以让它保持打开状态,但我遇到了一个问题,即期望它打开而它没有打开。

4

1 回答 1

3

我相信在连接上调用 close 方法而不在 reader 上调用它,你会得到一个异常。一个快速的解决办法就是在 WFConn.Close() 之前调用 reader.Close()。

或者,确保 WFConn 包含在 using 语句中 - 新连接。那么就不需要显式关闭连接了。它将通过 using 语句自动关闭和处置,读者也是如此。OleDbCommand 使用示例

public void ReadMyData(string connectionString)
{
    string queryString = "SELECT OrderID, CustomerID FROM Orders";
    using (OleDbConnection connection = new OleDbConnection(connectionString))
    {
        using (OleDbCommand command = new OleDbCommand(queryString, connection))
        {
            connection.Open();
            using (OleDbDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    Console.WriteLine(reader.GetInt32(0) + ", " + reader.GetString(1));
                }
            }
        }
    }
}

将它包装在语句和连接中OleDbDataReader是一种IDisposable很好的做法using,因此它的非托管资源可以更早地释放,而不是等到垃圾收集器调用读取器的 finalize 方法。这可以防止您忘记在阅读器以及连接上调用 close。编译器将为您生成一个 try/finally 块,并为每个块添加 close/dispose。您使用 OleDbCommand 实例正确地观察了 IDisposable 模式。

于 2013-11-01T11:39:44.187 回答