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

tug*_*erk 30 c# sql-server asp.net async-await

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

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的代码上有几个这样的操作.所以,我正在考虑将这些转换为异步.

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

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

编辑:

假设我重构代码如下:

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;

}
Run Code Online (Sandbox Code Playgroud)

据我所知,从await关键字,它将代码转换为继续.此外,当它命中await关键字时,无论操作状态如何,它都会立即返回其调用者.完成后,它会返回并触发延续代码.

这就是我的想法.

Rem*_*anu 56

我不同意Ricka的观点.异步数据库命令不仅好,它们在实现扩展,吞吐量延迟方面至关重要.他对线程池增加时间的反对意见仅适用于流量较低的Web服务器.

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

但是请注意:在启用Asynchronous Processing=true连接字符串之前,SQL命令不是真正的异步.虽然没有设置(默认情况下不是这样,编辑:从.NET Framework <4.5开始 Asynchronous Processing不再需要),你的'asyncronous'调用BeginExecuteReader只不过是假的,调用将启动一个线程并阻塞线程.如果在连接字符串中启用真正的异步处理,则该调用实际上是异步的,并且回调基于IO完成.

需要注意的是:一旦第一个结果返回到客户端,异步SQL命令就会完成,并且信息消息会计为结果.

create procedure usp_DetailsTagsGetAllFromApprovedPropsWithCount
as
begin
print 'Hello';
select complex query;
end
Run Code Online (Sandbox Code Playgroud)

你已经失去了异步的所有好处.在print建立了一个发送回客户端,这完成在客户端恢复异步命令和执行,并与"reader.Read()"继续的结果.现在将阻止,直到复杂查询开始产生结果.你问'谁print参与了这个程序?' 但是print可能是伪装成其他东西,或许是无辜的东西看起来像是INSERT没有先发布的情况下执行SET NOCOUNT ON.

  • 从.NET Framework 4.5开始,这些方法不再需要在连接字符串中使用Asynchronous Processing = true.http://msdn.microsoft.com/en-us/library/hh211418.aspx (9认同)
  • 从.Net 4.5开始,有新的[SqlDataReader.ReadAsync](http://msdn.microsoft.com/en-us/library/hh223681(v = vs.110).aspx)方法. (6认同)
  • 做这样设计决定的好领主?这些陷阱是荒谬的. (5认同)
  • 是的,但底层的异步功能来自`SqlClient`组件.Async团队正在利用现有的"IAsyncResult"功能构建语言和.Net Framework功能,而不是从头开始重新构建每个功能. (5认同)