手动处理SqlDbConnection导致"内部.net框架提供程序错误1"

时间:2018-03-01 21:56:41

标签: c# sql-server async-await

我正在写一个"数据访问层"风格图书馆。它只是一个C#库,它包含一堆执行SQL查询的函数。该库还提供了一个自定义的"会话"充当我的工作单元容器的对象,并管理我的SqlDbConnection

我的此会话类实现IDisposable,旨在using块中使用。在同一个会话类中,构造函数创建SqlDbConnection并打开连接。在调用会话类的Dispose方法之前,连接不会关闭。

在我的课程班级' Dispose方法,我调用Dispose的{​​{1}}方法。有时候,不是每次都会出现一个低级错误,只显示以下信息......

  

System.InvalidOperationException:'内部.Net框架数据   提供商错误1。'

使用提供的堆栈跟踪...

SqlDbConnection

在堆栈跟踪的底部,您可以看到我的 at System.Data.ProviderBase.DbConnectionInternal.PrePush(Object expectedOwner) at System.Data.ProviderBase.DbConnectionPool.PutObject(DbConnectionInternal obj, Object owningObject) at System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) at System.Data.SqlClient.SqlConnection.CloseInnerConnection() at System.Data.SqlClient.SqlConnection.Close() at System.Data.SqlClient.SqlConnection.Dispose(Boolean disposing) at System.ComponentModel.Component.Dispose() at Agent.Data.AgentSession.Dispose(Boolean disposeManagedResources) at Agent.Data.AgentSession.Finalize() 类,即"会话"我上面描述的班级,工作单位。您可以看到我的AgentSession功能所在的位置,然后您可以从中看到Dispose SqlConnection {/ p}}。

如果我在Dispose上致电DisposeClose,则会出现此问题。

我已经读过,这可能是因为我在尝试关闭连接时打开了SqlConnection。我的所有读者都在SqlDbReader块内。在我使用C#和using的10年中,我也从未遇到过这个问题,包括读者和关系。

现在,我在这个项目中做过的唯一一件我在过去的项目中从未做过的事情是广泛使用SqlConnectionasync。我使用SQL相关方法的所有异步版本。我的所有读者都使用Async方法等。

有人知道是什么原因造成的,或者我如何进一步调试这个?

这会导致Visual Studio 2017进入"中断模式"当发生这种情况时,这意味着我提供的唯一信息是上述错误消息和堆栈跟踪。 Visual Studio会在await上的Dispose来电中断。

编辑:

建议的副本确实指向了正确的解决方案。不过,我不想自动从这里重定向,因为这个问题获得了更好的回应,imo。我非常希望未来的读者能够在这个问题中看到评论和答案,因为这里的解释要好得多。

1 个答案:

答案 0 :(得分:4)

提到this表明这是一个在GC之后完成最终化的不受干扰的对象 - 可能是你没有正确关闭“代理”,它仍然引用一个对象。在终结器中,您不应触及任何其他托管对象。只是当前实例(~AgentSession() { Dispose(false); } )和任何非托管外部资源。含义:你可能有:

Dispose(false)

并且您的{{1}}代码正在做一些不应该做的事情。当然,另一个问题是你没有正确处理它。