C# 什么统计值对应于ADO.net SqlCommand.CommandTimeout属性?

C# 什么统计值对应于ADO.net SqlCommand.CommandTimeout属性?,c#,sql-server,ado.net,C#,Sql Server,Ado.net,我试图理解这个属性,我在ADO.net中有一个运行sql查询的函数,其中我将SqlCommand.ConnectTimeout属性设置为500秒,将SqlCommand.CommandTimeout属性设置为1秒。大致上,相关部分如下所示 var conn = dbConn as SqlConnection; conn.ConnectTimeout = 500; conn.StatisticsEnabled = true; try

我试图理解这个属性,我在ADO.net中有一个运行sql查询的函数,其中我将SqlCommand.ConnectTimeout属性设置为500秒,将SqlCommand.CommandTimeout属性设置为1秒。大致上,相关部分如下所示

        var conn = dbConn as SqlConnection;
        conn.ConnectTimeout = 500;
        conn.StatisticsEnabled = true;

        try
        {
            using (var command = new SqlCommand(query, conn))
            {
                command.CommandTimeout = 1;
                using (var adapter = new SqlDataAdapter(command))
                {
                    var rowsCount = adapter.Fill(startIdx, MaxRows, new DataTable[] { dtResult });
                    var stats = conn.RetrieveStatistics();
                    long commandExecutionTimeInMs = (long)stats["ExecutionTime"];
                    long commandNetworkServerTimeInMs = (long)stats["NetworkServerTime"];
                    Console.Writeline("Command statistics execution time: " + commandExecutionTimeInMs.ToString());
                    Console.Writeline("Command statistics network server time: " + commandNetworkServerTimeInMs.ToString());
                    conn.ResetStatistics();
                    conn.StatisticsEnabled = false;
                    return rowsCount;
                }
            }
        }
        catch (Exception ex)
        {
            var stats = conn.RetrieveStatistics();
            long commandExecutionTimeInMs = (long)stats["ExecutionTime"];
            long commandNetworkServerTimeInMs = (long)stats["NetworkServerTime"];
            Console.Writeline("Command statistics execution time: " + commandExecutionTimeInMs.ToString());
            Console.Writeline("Command statistics network server time: " + commandNetworkServerTimeInMs.ToString());
            conn.ResetStatistics();
            conn.StatisticsEnabled = false;
        } 
在这种情况下,我希望任何超过1秒的执行时间都会超时,并抛出一个异常,并显示以下消息:“执行超时已过期。操作完成前超时时间已过,或者服务器没有响应。”。然而,这是非常不一致的,我的日志告诉我,执行时间可以上升到几秒甚至10秒以上,有时不会抛出任何东西。NetworkServerTime始终在200到300ms的范围内

那么这里的问题是什么?我是否误解了命令超时的工作原理?我看到的是错误的统计值吗?我希望将CommandTimeout设置为1,然后当我的查询超过这个时间时,我可以清楚地看到一个统计信息,它在catch块中将时间记录为1s或1000ms


参考本页,似乎没有其他相关内容

文档中有备注和2个注释


在查阅了有关我使用的方法的文档和讨论之后,我想我找到了答案。对于使用SqlDataAdapter的人来说,这似乎不是一个新问题。引用一位微软工程师的话:

SqlCommand.CommandTimeout属性仅影响命令的单个操作。因此,超时设置将是单个执行期间所有网络读取的总时间,例如SqlCommand.ExecuteReader或SqlDataReader.Read()、SqlDataReader.GetString()。每次调用新操作时都会重置超时

SqlDataAdapter用户是命令的公共接口,因此它调用ExecuteReader一次,然后根据需要调用几个DataReader操作来检索数据。因此,总时间是(一次调用ExecuteReader+对命令执行其他操作)X CommandTimeout,具体取决于参数

参考:


我正在使用的SqlDataAdapter.Fill()方法可能正在执行多个操作,因此它很容易在执行时间上超过超时,但实际上不会触发异常。

您的连接属于using块。连接使用在其.Dispose方法中释放的非托管资源。连接需要调用其dispose方法。一个using块将处理这个问题。感谢提示,这实际上只是一个函数的一个片段,其中传递了连接,只是为了说明问题,连接本身在之后得到了正确的处理。我之前查看了文档,但这并不是我真正想要的答案。虽然它确实促使我搜索关于SqlDataAdapter的讨论,最终得到了我将单独发布的答案。
!Note

The CommandTimeout property will be ignored by older APM (Asynchronous Programming Model) asynchronous method calls such as BeginExecuteReader. It will be honored by newer TAP (Task Asynchronous Programming) methods such as ExecuteReaderAsync.

!Note

This property is the cumulative time-out (for all network packets that are read during the invocation of a method) for all network reads during command execution or processing of the results. A time-out can still occur after the first row is returned, and does not include user processing time, only network read time.

For example, with a 30 second time out, if Read requires two network packets, then it has 30 seconds to read both network packets. If you call Read again, it will have another 30 seconds to read any data that it requires.