使用ExecuteReaderAsync从C#AsyncCTP的任何不利 [英] Any disadvantage of using ExecuteReaderAsync from C# AsyncCTP

查看:1993
本文介绍了使用ExecuteReaderAsync从C#AsyncCTP的任何不利的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一些文章这表明,异步数据库调用在.NET坏主意。

There are some articles which indicate that async database calls are bad idea in .NET.

  • Should my database calls be Asynchronous?
  • Should my database calls be Asynchronous Part II

在C#异步CTP,有一个叫 System.Data.SqlClient.SqlCommand 扩展 ExecuteReaderAsync 。我有一些操作,如下对我现有的code:

On C# Async CTP, there is a System.Data.SqlClient.SqlCommand extension called ExecuteReaderAsync. I have some operations as below on my existing code:

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

有这样的几个操作上我的code。所以,我有上转换那些异步的想法。

There are several operations like this on my code. So, I am having thoughts on converting those to async.

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

But on the other hand, I am not seeing much attraction on this approach out there (maybe I am not looking at the right direction, who knows!).

那么,有没有在这里使用这个新的异步编程模型的任何缺点?

So, is there any disadvantages of using this new async programming model here?

编辑:

假设我重构如下code:

Assuming I refactor the code as below:

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了解,在转换code,这是后话,作为延续。此外,当它击中的await关键字,它立即返回给调用者无论工作状态。当它完成它回来和火的延续code。

As far as I understand from the await keyword, it converts the code, which is after it, as continuation. Also, when it hits the await keyword, it immediately returns to its caller regardless of the operation status. When it finishes it comes back and fire the continuation code.

这是我的想法。

推荐答案

我不同意Ricka这个。异步DB命令不仅是良好的,他们是在实现规模的关键,吞吐量的延迟。他对线程池的加速时间异议仅适用于低经历交通量的Web服务器。

I disagree with Ricka on this. Async DB commands are not only good, they are critical in achieving scale, throughput and latency. His objection about the ramp up time of the thread pool applies only to a web server that experiences low traffic volumes.

在一个高流量的情况下(这是唯一重要的一个),线程池将不必等待注入新主题。在做SQL命令异步不是仅仅从Web服务器请求/线程健康的角度,而且从视图总请求生命周期/等待时间点很重要:不相关的数据库调用可以并行进行,而不是按顺序。通常在HTTP请求的等待时间显着改善此单独的结果如由用户所经历。换句话说,你的网页加载速度。

In a high traffic situation (which is the only one that matters), the thread pool won't have to wait for 'injecting' new threads. Doing the SQL Commands asynchronously is important not only from the point of view of web server requests/threads health, but also from the point of view of total request lifetime/latency: uncorrelated DB calls can be done in parallel, as opposed to sequentially. This alone results usually in dramatic improvements in the latency of the HTTP request as experienced by the user. In other words, your pages load faster.

建议虽然一句话:SQL命令是不是真正的异步,直到您启用<一个href=\"http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.asynchronousprocessing.aspx\"><$c$c>Asynchronous处理=真 在连接字符串。虽然这是不设置(缺省情况下为不,的编辑:首先是.NET框架和LT; 4.5 <一个href=\"http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.asynchronousprocessing.aspx\"><$c$c>Asynchronous加工不再需要 的),你的'asyncronous调用<一个href=\"http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.beginexecutereader.aspx\"><$c$c>BeginExecuteReader都不过是一个骗局,呼叫将启动一个线程和块的的线程。当启用真正的异步处理的连接字符串中的的再调用真正异步和回调是基于IO完成。

A word of advice though: SQL Command is not truly asynchronous until you enable Asynchronous Processing=true on the connection string. While this is not set (and by default is not, starting with .NET Framework < 4.5. Asynchronous Processing is no longer required) your 'asyncronous' calls to BeginExecuteReader are nothing but a sham, the call will launch a thread and block that thread. When true async processing is enabled in the connection string then the call is truly async and the callback is based on IO completion.

一个忠告:异步SQL命令将立即完成的的第一个的结果返回给客户端,以及信息消息算作结果

A word of caution: an async SQL command is completing as soon as the first result returns to the client, and info messages count as result.

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

您已经失去了异步的所有优点。在打印创建被发送回客户端,完成在客户恢复异步命令和执行,并与reader.Read()'继续的结果。现在的的将阻塞,直到复杂查询开始生产的结果。你问的'谁把打印中的过程?的,但打印,可能会变相别的东西,或许是因为无辜的看着为插入一个执行的没有的第一个发出的 SET NOCOUNT ON

You've lost all benefits of async. The print creates a result that is sent back to the client, which completes the async command and execution on the client resumes and continues with the 'reader.Read()'. Now that will block until the complex query start producing results. You ask 'who puts print in the procedure?' but the print may be disguised in something else, perhaps something as innocent looking as an INSERT that executes without first issuing a SET NOCOUNT ON.

这篇关于使用ExecuteReaderAsync从C#AsyncCTP的任何不利的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆