DataReader Close方法引发OdbcException

时间:2011-02-25 22:58:41

标签: c# odbc datareader

更新:很抱歉周末有延迟,但您的评论有些更新:我更新了堆栈跟踪以包含整个堆栈。同样,当我通过DataReader.Close()手动关闭阅读器时,问题仍然存在。我使用的数据库只是一个Microsoft Access数据库。最后,如果我捕获OdbcException,这是异常中的信息:

OdbcException: 数据:System.Collections.ListDictionaryInternal
ErrorCode:-2146232009(很可能没有帮助)
错误:System.Data.OdbcErrorCollecion
HelpLink:[空白]
InnerException:[blank]
消息:[空白]
资料来源:[空白]
TargetSite:Void StatementErrorHandler(RetCode)

结束更新。

在调试时,OdbcDataReader.Close()方法在Visual Studio中是否正常运行是否有任何原因,但是当EXE在Visual Studio外部运行时会在Close方法上抛出OdbcException?

一点背景:我有一个应用程序与数据库执行一些基本的交互,我一直在使用Database类中保存的标准格式(如下所示)与数据库进行交互。这个类已经工作了大约6个月,最近它只在程序从EXE运行时才开始崩溃。当DataReader关闭时(在using语句结束时,它将抛出未处理的异常OdbcException。如果调用Close()方法,则会抛出相同的异常)。异常的堆栈跟踪是(更改了一些名称):

at System.Data.Odbc.CMDWrapper.StatementErrorHandler(RetCode retcode)  
at System.Data.Odbc.CMDWrapper.FreeStatementHandle(STMT stmt)  
at System.Data.Odbc.OdbcDataReader.Close(Boolean disposing)  
at System.Data.Odbc.OdbcDataReader.Dispose(Boolean disposing)  
at System.Data.Common.DbDataReader.Dispose()  
at Namespace.DatabaseManag.Retrieve(String column, String table) in C:\Program\CommonFiles\DatabaseManag.cs:line 81  
at Namespace.Parameters.LoadData() in C:\UserControls\Parameters.cs:line 49  
at Namespace.MainScreen.OnLoad(Object sender, EventArgs e) in C:\Program\MainScreen.cs:line 99  
at System.Windows.Forms.Form.OnLoad(EventArgs e)  
at System.Windows.Forms.Form.OnCreateControl()  
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)  
at System.Windows.Forms.Control.CreateControl()  
at System.Windows.Forms.Control.WmShowWindow(Message& m)  
at System.Windows.Forms.Control.WndProc(Message& m)  
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)  
at System.Windows.Forms.ContainerControl.WndProc(Message& m)  
at System.Windows.Forms.Form.WmShowWindow(Message& m)  
at System.Windows.Forms.Form.WndProc(Message& m)  
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)  
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)  
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

从Visual Studio启动时,一切正常。只有在运行EXE时才会出现此问题。通过大量的试验和错误,我能够从Database类中删除各个部分,直到我可以在一个可行的方法和一个抛出异常的方法之间缩小范围。两种方法之间的唯一区别是如下所示的空catch子句:

不起作用的方法:

public List<string> Retrieve(string column, string table)
{
    List<string> Results = new List<string>();
    try
    {
        using (OdbcConnection Conn = new OdbcConnection("DSN=DSNNAME"))
        {
            using (OdbcCommand Command = new OdbcCommand("select " + column + " from " + table, Conn))
            {
                Conn.Open();
                using (OdbcDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        Results.Add(Reader.GetString(0));
                    }
                } //This is the line that it will fail on
            }
        }
    }
    finally
    {
    }
    return Results;
}

有效的方法(通过工作,我的意思是仍然可以正确读取和返回来自数据库的信息,但忽略了异常):

public List<string> Retrieve(string column, string table)
{
    List<string> Results = new List<string>();
    try
    {
        using (OdbcConnection Conn = new OdbcConnection("DSN=DSNNAME"))
        {
            using (OdbcCommand Command = new OdbcCommand("select " + column + " from " + table, Conn))
            {
                Conn.Open();
                using (OdbcDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        Results.Add(Reader.GetString(0));
                    }
                }
            }
        }
    }
    catch
    {
    }
    finally
    {
    }
    return Results;
}

我找不到发生这种情况的原因。当试图在一个单独的项目中复制它时,它不会抛出异常,这使我相信与我的特定项目有关。但是,当将空白catch子句添加到完整的Database类中时,它仍会抛出异常。

有谁知道为什么会这样?我感觉有些东西已经损坏,但重新安装所有相关的应用程序都没有效果。

3 个答案:

答案 0 :(得分:0)

抓住异常并查看它: catch(Exception ex)

答案 1 :(得分:0)

关于关闭与访问数据库的连接可能存在竞争条件,这只是一个文件,特别是如果你只能在开发环境运行时之外重现它,这可能稍微快一点。

如果在代码中引入一个小睡眠会怎样?

using (OdbcDataReader Reader = Command.ExecuteReader())
{
    while (Reader.Read())
    {
        Results.Add(Reader.GetString(0));
    }
    Thread.Sleep(TimeSpan.FromMilliseconds(100));
}

请注意,这可能不是一个好的“生产代码”解决方案,但如果它修复了它,也许它可能是唯一可以解决的问题。捕捉和吞咽异常最有可能至少燃烧100毫秒。如果确实如此,我会留下它,但也添加一个特定的catch来检查预期的“无害”异常,只有在它确实是确切的异常时才会吞下它,否则重新抛出它。

答案 2 :(得分:0)

经过多次试验和错误后,我终于确定了问题。奇怪的是,有人也遇到了这个问题,我想我会回答我自己的问题。

在完全重新创建我的项目并且仍然无法复制错误或获得比Odbcexception更多的信息之后,我发现了一个程序,应用程序验证程序(不完全确定它共享此计算机后它做了什么)附加到该进程。每次我的项目在Visual Studio之外运行时,应用程序验证程序很可能附加到我的exe进程并导致错误。打开应用程序验证程序并删除对我的项目的exe和所有日志文件的引用似乎已修复该问题。

我可以看到这可能是怎么可能导致我的错误但我不知道为什么DataReader.Close()它会错误的代码行。如果有人知道并愿意分享,我会感兴趣。