【问题标题】:AccessViolationException on OdbcDataReader.Dispose()OdbcDataReader.Dispose() 上的 AccessViolationException
【发布时间】:2009-09-12 07:59:59
【问题描述】:

在刚刚从数据库中检索数据后处理 OdbcDataReader 时,我遇到了这个异常。阅读器实际上是在离开 Using 块时被处置的。据我所知,这不应该导致任何错误。有什么想法吗?

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 数据库

【问题讨论】:

  • 你的问题解决了吗?
  • 它随机发生了几次,然后就停止了,我没有改变任何东西......对我来说似乎完全随机。

标签: .net access-violation


【解决方案1】:

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

快速搜索OdbcDataReader + AccessViolationException 表明这并不罕见 - 但问题中没有足够的信息(数据库?场景?)来缩小范围。就我个人而言,我会首先查看一些 google 命中...(可能由您的 rdbms 过滤)。

【讨论】:

  • 来自堆栈跟踪:它在 Dispose() 中
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    使用保证来清理对象 - 但它不能保证保持该对象处于活动状态。 [终结器可以在最后一次调用对象的实例方法期间启动。因此终结器可以在 dispose 调用期间启动。如果这发生得足够早,就好像在 dispose 之前调用了终结器。]

    如果这是真的,并且 OBDC 对您来说是一个黑匣子,那么您能做的最好的事情就是尝试一种解决方法。

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

    有关 dispose 和 finalizers 令人头疼的完整概述,请参阅:GC Discussion 这是一个非常详细的讨论。

    【讨论】:

    • "但它不能保证该对象保持活动状态。" - 你能做到吗?为了调用 Dispose(),变量仍然必须在范围内考虑;对变量进行了读取,因此在此之前不应收集它...?
    • 我已经用一个很好的链接更新了我的帖子以获得更多详细信息并澄清了我的意思 - 我希望这会有所帮助。
    猜你喜欢
    • 2019-11-26
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2021-01-04
    相关资源
    最近更新 更多