【问题标题】:Very slow HttpClient SendAsync call非常慢的 HttpClient SendAsync 调用
【发布时间】:2020-07-09 04:20:22
【问题描述】:

阅读其他答案后,我不明白为什么 SendAsync 这么慢。

从 Postman 调用相同的端点,我在 160 毫秒内得到响应。

从下面的代码调用,需要 10 秒。我正在使用 C# 桌面应用程序进行调用。

public static async Task<string> GetToken()
{

    var url = "....";

    var dict = new Dictionary<string, string>();
    dict.Add("username", "foo");
    dict.Add("password", "bar");

    using (var client = new HttpClient(
        new HttpClientHandler
        {
            Proxy = null,
            UseProxy = false
        }))
    {
        //bypass SSL
        ServicePointManager.ServerCertificateValidationCallback = new
            RemoteCertificateValidationCallback
            (
                delegate { return true; }
            );
        var req = new HttpRequestMessage(HttpMethod.Post, url) { Content = new FormUrlEncodedContent(dict) };
        var res = await client.SendAsync(req); //10 seconds here!
        if (res.StatusCode != HttpStatusCode.OK)
            return string.Empty;

        var token = await JsonConvert.DeserializeObject<TokenResponse>(res.Content.ReadAsStringAsync());
        return token.access_token;
    }
}

【问题讨论】:

  • using (var req = new HttpRequestMessage(...)) { ... }Using objects that implement IDisposable
  • using (var client = new HttpClient ... - 错误,因为 HttpClient 旨在为每个应用程序实例化一次,而不是每次使用。
  • @aepot 你在这两点上都是正确的,但这不会导致延迟。
  • @aepot,问题是要实例化每个请求。谢谢。
  • @aepot,我会很感激的。

标签: c# asp.net


【解决方案1】:

您的代码很复杂并忽略了IDisposable,而这个:HttpClient 旨在为每个应用程序实例化一次,而不是每次使用。

为其他类型的请求创建可重用的方法

private static readonly HttpClient client = new HttpClient();

private async Task<T> PostDataAsync<T>(string url, Dictionary<string, string> formData)
{
    using (HttpContent content = new FormUrlEncodedContent(formData))
    using (HttpResponseMessage response = await client.PostAsync(url, content).ConfigureAwait(false))
    {
        response.EnsureSuccessStatusCode(); // throws if 404, 500, etc.
        string responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        return JsonConvert.DeserializeObject<T>(responseText);
    }
}

用法

public static async Task<string> GetToken()
{
    var url = "....";

    var dict = new Dictionary<string, string>();
    dict.Add("username", "foo");
    dict.Add("password", "bar");

    try
    {
        TokenResponse token = await PostDataAsync<TokenResponse>(url, dict);
        return token.access_token;
    }
    catch (HttpRequestException ex)
    {
        // handle Exception here
        return string.Empty;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 2020-08-07
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    相关资源
    最近更新 更多