OdbcDataReader.Dispose()上的AccessViolationException

时间:2009-01-08 06:42:59

标签: .net access-violation

我在从数据库中检索数据后立即处理OdbcDataReader时遇到此异常。在离开使用块时实际处理读取器。据我所知,这不应该导致任何错误。有什么想法吗?

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Data.Common.UnsafeNativeMethods.SQLFreeStmt(OdbcStatementHandle StatementHandle, STMT Option)
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 MyNamespace.MyClass.MyFunction() in C:\myfile.vb:line 100

谢谢!

编辑:使用Sybase ASE 12.5数据库

3 个答案:

答案 0 :(得分:0)

Dispose()中是否抛出了异常?还是在那之前呢? Dispose()投掷是不好的做法,但并非闻所未闻。有时(例如,with WCF)需要吞下这些,但在这种情况下,错误听起来像是不应该被吞下的东西。

快速搜索OdbcDataReader + AccessViolationException表明这并不罕见 - 但问题中没有足够的信息(数据库?方案?)来缩小范围。就个人而言,我首先要看一些谷歌点击...(可能是你的rdbms过滤了)。

答案 1 :(得分:0)

您正在使用的ODBC驱动程序中可能存在错误。

答案 2 :(得分:0)

一般而言,管理/非管理交互在生命周期管理方面可能会很麻烦。

这看起来像是在OdbcDataReader中的dispose和终结器之间的竞争条件,它可能正在删除一些处理也试图清理的非托管对象。 他们可能都调用SQLFreeStmt。

使用保证清理对象 - 但不保证保持该对象存活。 [终结器可以在最后一次调用对象上的实例方法时启动。因此,终结者可以在处理呼叫期间启动。如果这种情况发生得足够早,就好像在处理之前调用终结器一样。]

如果这是真的,并且如果OBDC的东西是黑盒子,那么你可以做的最好就是尝试解决方法。

我会尝试在使用范围结束前的最后一行添加System.GC.KeepAlive(your_DbDataReader_object)。

有关头痛和终结者的完整概述,请参阅:GC Discussion 这是一个非常详细的讨论。