在POST期间双击等待操作

时间:2015-06-29 17:31:10

标签: c# performance asynchronous async-await dotnet-httpclient

使用c#HttpClient来发布数据,假设我也关注返回的内容。我正在优化我的应用程序,并尝试在同一方法中了解两个等待调用的性能影响。从以下代码段

中弹出了问题
public static async Task<string> AsyncRequest(string URL, string data = null)
{
    using (var client = new HttpClient())
    {
        var post = await client.PostAsync(URL, new StringContent(data, Encoding.UTF8, "application/json")).ConfigureAwait(false);
        post.EnsureSuccessStatusCode();

        var response = await post.Content.ReadAsStringAsync();
        return response;
    }
}

假设我有错误处理:) 我知道等待电话很贵,所以双重等待引起了我的注意。

  • 在第一次await完成后,POST响应在内存中,直接返回结果会更有效,例如var response = post.Content.ReadAsStringAsync().Result;
  • 在同一方法中进行两次await / async调用时有哪些性能考虑因素?
  • 上面的代码是否会导致每个等待线程(2个线程),或者返回的任务中的1个线程将处理两个await调用?

1 个答案:

答案 0 :(得分:8)

  

我知道等待电话很贵,所以双人等待抓住我的电话   注意。

为什么你会说他们很贵?编译器生成的状态机是一个高度优化的野兽,它确保它不会臃肿内存。根据具体情况,例如,从TaskAwaiter返回的Taskstruct而不是class,因此它不会在堆上分配。正如@usr所指出的那样,非常正确的是,通过线路发送请求会使任何状态机分配成本都可以忽略不计。

  

直接返回结果会更有效,例如var response = post.Content.ReadAsStringAsync().Result;

标记方法async足以让编译器生成状态机。堆栈变量已经被提升到创建的状态机。一旦你的第一个await被击中,你的其余代码无论如何都会变为延续。使用post.Content.ReadAsStringAsync().Result;更有可能导致死锁代码,而不是节省内存消耗或使代码快一毫秒。

  

制作两个await / async时的性能考虑因素   用相同的方法调用?

从性能角度来看,你应该问自己的是:并发性在我的应用程序中是一个问题,这使得使用异步操作值得吗?

async在大量消费者会打你的地方闪闪发光,并且你想确保你有足够的可用资源来处理这些请求。我看到人们问了很多次&#34;为什么这个异步代码没有让我的代码变得更快?&#34;。它赢得做出任何明显的改变,除非你将面临繁重的流量,足够重,例如,你将强调你的IIS线程池实际上它将实际上从异步中受益。

  

以上代码是否会导致每个等待线程(2个线程)或1   返回任务的线程将处理两个等待调用?

取决于您的环境。当您的第一个await被点击时,您明确告诉它不要用ConfigureAwait(false)封送任何同步上下文。例如,如果您从UI线程运行此命令,那么PostAsync之后的任何代码都将在线程池工作线程上运行。同样,这对您来说不应该是一个问题,这些都是微观优化,您不会从中获益。