有一些文章指出,异步数据库调用是一个坏主意.网

在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();
    }
}

在我的代码中有几种类似的操作.所以,我正在考虑将它们转换为异步.

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

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

Edit:

假设我重构代码如下:

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关键字了解,它将其后面的代码转换为continuation.此外,当它点击wait关键字时,无论操作状态如何,它都会立即返回调用方.当它完成时,它会返回并触发延续代码.

这就是我的 idea .

推荐答案

我不同意里卡的观点.异步DB命令不仅很好,而且在实现规模、吞吐量和延迟方面非常关键.他对线程池启动时间的异议只适用于流量较低的web服务器.

在高流量情况下(这是唯一重要的情况),线程池将不必等待"注入"新线程.异步执行SQL命令不仅从Web服务器请求/线程运行状况的Angular 来看很重要,而且从总请求生存期/延迟的Angular 来看也很重要:可以并行执行不相关的DB调用,而不是按顺序执行.仅此一项通常就会导致用户体验到的HTTP请求等待时间的显著改善.换句话说,您的页面加载速度更快.

不过有一点建议:在连接字符串上启用Asynchronous Processing=true之前,SQL命令并不是真正的异步命令.虽然没有设置(默认情况下不是Edit: starting with .NET Framework < 4.5. 101),但对BeginExecuteReader的"异步"调用只不过是一个假的,调用将启动一个线程并阻塞that线程.如果启用了true async processing in the connection string,则调用是真正异步的,回调基于IO完成.

警告:当first个结果返回到客户机时,异步SQL命令将立即完成,信息消息将作为结果计数.

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

你已经失go 了异步的所有好处.print创建一个结果,并将其发送回客户机,客户机完成异步命令,然后在客户机上继续执行"reader".读().现在that将阻塞,直到复杂查询开始生成结果.你问'who puts 101 in the procedure?',但print可能被伪装成了别的东西,也许像INSERT先执行without再发出SET NOCOUNT ON一样无辜.

Asp.net相关问答推荐

由于 Blazor Change Detection API,组件重新渲染被跳过.如何避免?

$(document).ready 不工作

如何在 ASP.Net Core 中验证上传的文件

DBSet 不包含 Where 的定义

如何正确配置 IHttpModule?

如何在 C# 代码中获取当前项目名称?

使用会话变量有多安全 - asp.net / c#

ASP.NET GridView 第二个标题行跨越主标题行

判断会话是否为空

使用 jQuery.ajax() 时如何处理错误?

多个 DataContext 类是否合适?

如何在集线器类之外获取 SignalR 用户连接 ID?

使用 Lucene.NET 索引 .PDF、.XLS、.DOC、.PPT

ASP.NET 中的 <% %>(嵌入式代码块)

为应用程序池Classic .NET AppPool提供服务的进程与 Windows 进程激活服务发生了致命的通信错误

使用 LINQ 进行递归控制搜索

asp.net 网站上的第一页加载缓慢

如何判断本地主机

ASP.NET:在 Response.Redirect(...) 之后代码会发生什么?

Application_End global.asax