Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从ExecuteReader内部解决正在关闭的SqlConnection?_C#_.net_Sql Server 2005 - Fatal编程技术网

C# 如何从ExecuteReader内部解决正在关闭的SqlConnection?

C# 如何从ExecuteReader内部解决正在关闭的SqlConnection?,c#,.net,sql-server-2005,C#,.net,Sql Server 2005,我有一个openSqlConnection,代码如下: using (var transaction = connection.BeginTransaction()) { using (var command = connection.CreateCommand()) { command.Transaction = transaction; command.CommandText = "MyQueryText"; using( var reader = c

我有一个open
SqlConnection
,代码如下:

using (var transaction = connection.BeginTransaction()) {
   using (var command = connection.CreateCommand()) {
       command.Transaction = transaction;
   command.CommandText = "MyQueryText";
       using( var reader = command.ExecuteReader() ) {
           //read data
       }
   }
}
订阅了
SqlConnection.StateChange
event,现在我发现在某个时候,该事件是通过以下堆栈调用的(状态从
Open
更改为
Closed
):

因此,运行时遇到一些随机错误(我猜是网络连接问题),关闭连接,然后将一个关闭的读卡器对象返回给我的代码,我尝试使用返回的读卡器时产生
invalidooperationexception

我需要设法解决这个问题。显然,随机网络错误会发生。我的代码中有重试逻辑,可以处理在网络问题上抛出的
SqlException
s,但这里我面对的是一个关闭的读卡器,然后是
invalidooperationexception

我的第一个想法是编写我自己的
ExecuteReader()
,调用native
ExecuteReader()
,检查是否返回了一个已关闭的读取器,如果出现这种情况,抛出一个新的
ClosedReaderReturnedException
,我还将更改重试代码,以便它也对此类异常做出反应,并重新运行查询


我的解决方案好吗?有更好的解决方案吗?

基于任何异常(而不是特定的SqlException)的重试逻辑是否存在任何问题?我假设由于编程错误导致的异常最终会在测试阶段被发现,严重的(比如)异常无论如何都不会被catch块捕获,所以用于重试逻辑的通用异常块是可以接受的


如果不是,那么包装
ExecuteReader
的解决方案可能是个好主意。考虑到这是一种行为,您还需要注意ExecuteReader方法可能引发的其他异常-因此您可能需要预测
IOException
ObjectDisposedException
,除了
InvalidOperationException
之外,还要在connect网站上提交一个bug。如果你在比赛中抛球会发生什么?你的异常会备份到execute reader吗?@AbdElRaheim:我会提交一个bug,但修复它需要很长时间,或者他们甚至会“按设计”关闭它,我现在需要一个解决方法。这是不可靠的复制,所以我不能真正测试它彻底。有可能检查连接状态后,你调用executereader?也许可以创建一个扩展方法,在命令上调用executereader,然后检查连接状态。也可能是read()的一个方法,它也可以执行相同的操作check@AbdElRaheim:这差不多就是我的建议,不是吗?哦。这是一个很好的解决方案:)重试任何异常都是一个坏主意——它会引发对外部服务的毁灭性请求风暴,并使一切瘫痪。
at MyHandler.onStateChange(Object sender, StateChangeEventArgs e)
at System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Close()
at System.Data.SqlClient.SqlInternalConnectionTds.BreakConnection()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.ReadByte()
at System.Data.SqlClient.SqlDataReader.SetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader()
// my code calling `ExecuteReader()`