c# - 从 C# AsyncCTP 使用 ExecuteReaderAsync 的任何缺点

标签 c# asp.net sql-server async-await

有一些文章表明异步数据库调用在 .NET 中不是一个好主意。

在 C# Async CTP 上,有一个名为 ExecuteReaderAsyncSystem.Data.SqlClient.SqlCommand 扩展。我对我现有的代码有如下一些操作:

var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString;

using (var conn = new SqlConnection(connectionString)) {
    using (var cmd = new SqlCommand()) {

        cmd.Connection = conn;
        cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount";
        cmd.CommandType = System.Data.CommandType.StoredProcedure;

        conn.Open();

        var reader = cmd.ExecuteReader();
        while (reader.Read()) {

            //do the reading

        }

        conn.Close();
    }
}

我的代码中有几个这样的操作。所以,我正在考虑将它们转换为异步。

但另一方面,我看不到这种方法有多大吸引力(也许我没有看到正确的方向,谁知道呢!)。

那么,在这里使用这种新的异步编程模型有什么缺点吗?

编辑:

假设我重构代码如下:

public async Task<IEnumerable<Foo>> GetDataAsync() { 

    List<Foo> foos = new List<Foo>();

    var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString;

    using (var conn = new SqlConnection(connectionString)) {
        using (var cmd = new SqlCommand()) {

            cmd.Connection = conn;
            cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            conn.Open();

            var reader = await cmd.ExecuteReaderAsync();
            while (reader.Read()) {

                //do the reading
                //create foos

            }

            conn.Close();
        }
    }

    return foos;

}

据我对 await 关键字的理解,它将其后的代码转换为延续。此外,当它遇到 await 关键字时,它会立即返回其调用者,而不管操作状态如何。当它完成时,它会返回并触发继续代码。

这就是我的想法。

最佳答案

在这一点上我不同意 Ricka。异步数据库命令不仅很好,而且对于实现规模、吞吐量延迟也很关键。他对线程池启动时间的反对意见仅适用于流量较低的 Web 服务器。

在高流量情况下(这是唯一重要的情况),线程池不必等待“注入(inject)”新线程。异步执行 SQL 命令不仅从 Web 服务器请求/线程健康的角度来看很重要,而且从总请求生命周期/延迟的角度来看也很重要:不相关的数据库调用可以并行执行,而不是顺序执行。仅此一项通常就会显着改善用户体验到的 HTTP 请求的延迟。换句话说,您的页面加载速度更快。

不过有一点忠告:在启用 Asynchronous Processing=true 之前,SQL 命令不是真正的异步命令。在连接字符串上。虽然未设置(默认情况下未设置,编辑:从 .NET Framework < 4.5 开始。Asynchronous Processing is no longer required )您对 BeginExecuteReader 的“异步”调用只不过是一个骗局,该调用将启动一个线程并阻止那个线程。当在连接字符串中启用真正的异步处理时,调用就是真正的异步,并且回调基于 IO 完成。

请注意:第一个结果返回客户端后,异步 SQL 命令即完成,信息消息也算作结果。

create procedure usp_DetailsTagsGetAllFromApprovedPropsWithCount
as
begin
print 'Hello';
select complex query;
end

您已经失去了异步的所有好处。 print 创建一个发送回客户端的结果,该结果完成异步命令并在客户端恢复执行并继续“reader.Read()”。现在 that 将阻塞,直到复杂查询开始产生结果。您问“谁将 print 放在程序中?”print 可能伪装成其他东西,也许看起来像 INSERT 执行 首先发出 SET NOCOUNT ON .

关于c# - 从 C# AsyncCTP 使用 ExecuteReaderAsync 的任何缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9432647/

相关文章:

c# - Umbraco 应用程序 BeginRequest 从未触发

jquery - 正确响应从 ASP.NET 页面发送的 jquery.ajax json 数据

javascript - 基本 Entity Framework Web API : The INSERT statement conflicted with the FOREIGN KEY constraint

asp.net - $find() 在 IE 9 中返回 null

c# - 我如何获得 about 方法来读取变量?

c# - 如何表示整数无穷大?

c# - RSA SHA256 签名生成和验证

sql-server - 忽略 SSIS 的 OLE DB 目标中的重复记录

sql - 为每一表行创建一个 json

c# - Entity Framework 4.3.1 无法创建(/打开)数据库 [线程异常?]