更新:很抱歉周末有延迟,但您的评论有些更新:我更新了堆栈跟踪以包含整个堆栈。同样,当我通过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类中时,它仍会抛出异常。
有谁知道为什么会这样?我感觉有些东西已经损坏,但重新安装所有相关的应用程序都没有效果。
答案 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()它会错误的代码行。如果有人知道并愿意分享,我会感兴趣。