c# - POST 期间的双重等待操作

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

使用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/

相关文章:

php - 分析 PHP 应用程序,50% 的时间忙于构建类——这样可以吗?

c - 使用 SSE 从 _m128i 寄存器中提取非零值

Java 7 Calendar.getInstance、TimeZone.getTimeZone 同步且速度慢,有什么解决方法吗?

javascript - 如何重写异步函数(node.js、monk)

c# - 在单独的程序集中使用受约束的通用扩展方法会产生引用错误

c# - 无法将类型 'System.Collections.ArrayList' 的对象强制转换为类型 'System.Collections.Generic.IEnumerable'

c# - 如何通过 ID 向 signalR 特定的 PersistentConnection 发送消息? (使用 asp.net mvc4 web-api)

java - 如何在 Java 中执行此 C# return 语句

javascript - 使用 promise 时的逻辑流程

javascript - 异步加载 javascript,然后在执行回调之前检查加载的 DOM