.NET 3.5 中的"An existing connection was forcibly closed by the remote host"



我正在编写一个查看、归档和恢复sql数据的程序。这个问题只发生在恢复和使用目标框架.NET 3.5时。.NET 4.0和更高的版本似乎已经解决了这个问题,但是我必须用3.5来编写程序,以保证与应该使用它的计算机完全兼容。

下面的方法被调用了几次(5-10),以获得数据库表的所有名称:

public List<string> GetAllTables(string sDatabase)
{
List<string> result = new List<string>();
try
{
using (SqlConnection con = new SqlConnection(dbConnection.conString + sDatabase))
{
con.Open();
using (SqlCommand command = new SqlCommand("SELECT name FROM sys.Tables", con))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
result.Add(reader["name"].ToString());
}
}
}
}
return result;
}
catch (SqlException sqlEx)
{
string methodName = (new System.Diagnostics.StackTrace()).GetFrame(0).GetMethod().Name;
string className = (new System.Diagnostics.StackTrace()).GetFrame(0).GetMethod().DeclaringType.Name;
Debug.Print("Error in class {0} - method: {1}: {2}", className, methodName, sqlEx.Message);
return result;
}
}

错误发生在var reader = command.ExecuteReader()。奇怪的是,这种情况并不是每次都发生。每秒钟恢复一次都是成功的,并且不会抛出错误。

异常堆栈跟踪如下:

Error in class DatabaseWorker - method: GetAllTables: Transmission-level error when sending the request to the server. (provider: TCP-Provider, error:0 - An existing connection was closed by the remote host.)
at System.Data.SqlClient.SqlConnection.onError(SQLException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.WriteSni()
at System.Data.SqlClient.TdsParserStateObject.ExecuteFlush()
at System.Data.SqlClient.TdsParser.TdsExecuteSQLBatch(String text, Int32 timeout, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj)
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()
for sql_data archiving.fashion model.DatabaseWorker.GetAllTables(String sDatabase)

实际上,SQL服务器正在关闭与您的连接。

我发现使用SQL时的传输级别错误通常与身份验证相关,特别是涉及集成安全性时。它可能与Windows Domain相关(比如SQL如何评估连接的身份)。有时我发现这些问题可以通过重新启动SQL Server来解决,但这些问题是针对持久连接问题(而不是您所拥有的)。如果您正在使用集成安全性,请尝试使用SQL帐户(用户名/密码)。

至于为什么有时会出现问题,考虑到你想在。net 3.5框架上运行,这并不容易(可能在以后的运行时中已经修复了一个潜在的问题)。

我可以建议一些方法

  • 尝试使用SQL帐户
  • 建立连接
  • 如果你必须保持在。net 3.5,在你的代码中实现一个重试策略(比如3次,延迟1秒,失败之前)。
  • 考虑使用。net Core作为一个独立的版本(--self-contained)来构建应用程序。这将打包所有依赖项,包括运行时。也就是说,在部署应用时不需要安装运行时。

对于使用SQL服务器执行管理工作,有一个名为Microsoft.SqlServer.SqlManagementObjects的nuget包,其中包含丰富的功能,如定义备份集等。它在。net 3.5中不可用,但在。net Core中有一个自包含的部署,对于未来的工作可能是一个有用的选择。

相关内容

最新更新