使用c# HttpClient 来POST 数据,假设我也关心返回的内容。我正在优化我的应用程序并尝试了解同一方法中两次等待调用对性能的影响。从以下代码片段中弹出问题,
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 调用时,性能方面的考虑因素是什么?
- 上面的代码会导致每个 await 一个线程(2 个线程),还是 1 个线程用于处理两个 await 调用的返回任务?
最佳答案
I know await calls are expensive so the double await caught my attention.
为什么说贵?编译器生成的状态机是一个高度优化的野兽,确保它不会膨胀内存。具体来说,例如,从 Task
返回的 TaskAwaiter
是一个 struct
而不是 class
所以它不会在堆上分配。正如 @usr 所指出的,并且非常正确,通过网络发送请求将使任何状态机分配成本都可以忽略不计。
would it be more efficient to return the result directly, like
var response = post.Content.ReadAsStringAsync().Result;
标记您的方法 async
足以让编译器生成状态机。堆栈变量已经被提升到创建的状态机。一旦你的第一个 await
被命中,你的代码的其余部分无论如何都会变成一个延续。使用 post.Content.ReadAsStringAsync().Result;
更有可能导致您的代码死锁,而不是为您节省任何内存消耗或使您的代码更快微毫秒.
What are the performance considerations when making two await/async calls in the same method?
从性能的角度来看,您应该问自己的问题是:并发性是否会成为我的应用程序中的一个问题,从而值得使用异步操作?
async
在大量消费者会攻击您的地方大放异彩,并且您想确保您有足够的可用资源来处理这些请求。我看到人们多次问“为什么这个异步代码不能让我的代码运行得更快?”。它不会做出任何显着的改变,除非您将处于繁忙的流量之下,例如,您将对 IIS 线程池施加压力,而 IIS 线程池实际上会从异步中获益。
Will the above code result in a thread per await (2 threads), or 1 thread for the returned Task that will handle both await calls?
取决于您的环境。当您的第一个 await
被命中时,您明确告诉它不要使用 ConfigureAwait(false)
编码任何同步上下文。例如,如果您从 UI 线程运行它,则 PostAsync
之后的任何代码都将在线程池工作线程上运行。同样,这对您来说不应该是一个问题,这些是微优化,您不会从中看到任何好处。
关于c# - POST 期间的双重等待操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31121956/