".NET 3.5中出现“现有连接被远程主机强制关闭”的错误"

3

我正在编写一个用于查看、存档和还原 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)
1个回答

3

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

我发现,在与 SQL 交互时出现传输级别错误通常与身份验证相关,特别是涉及集成安全性时。可能涉及到 Windows 域相关的问题(例如 SQL 如何评估连接的标识)。有时候,这些问题可以通过重新启动 SQL Server 来解决,但那些是针对持久连接问题的(与您的情况不同)。如果您使用集成安全性,请尝试使用 SQL 账户(用户名/密码)。

至于为什么这是一个偶发性的问题,这并不容易考虑,因为您想在 .NET 3.5 Framework 上运行(很可能基础问题已在以后的运行时中得到修复)。

我可以提供一些方法:

  • 尝试使用 SQL 账户进行连接
  • 如果您必须保留 .NET 3.5,请在代码中实现重试策略(例如尝试 3 次,在失败之前延迟 1 秒)。
  • 考虑使用 .NET Core 构建应用程序作为自包含版本(--self-contained)。这将打包所有依赖项,包括运行时。也就是说,部署应用程序时无需安装运行时。

要使用 SQL 服务器执行管理工作,有一个名为Microsoft.SqlServer.SqlManagementObjects的NuGet软件包,其中包括定义备份集等丰富的功能。它不适用于 .NET 3.5,但是对于 .NET Core 中的自包含版本,它可能是未来工作的一个有用选择。


谢谢。我会尝试你的建议。 - aaronwe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接