【问题标题】:C# HttpClient POST'ing AsyncC# HttpClient POST'ing 异步
【发布时间】:2016-11-30 02:31:09
【问题描述】:

我想发送一个可能需要几秒钟才能回复而不冻结我的 UI 的 http 帖子,目前此代码只是在调用该方法时挂起我的应用程序。

我做错了什么以及如何实现我的目标?

private async Task<string> DoHttpClientPost(string method, IDictionary<string, object> args = null)
    {
        {
            HttpClientHandler handler = new HttpClientHandler()
            {
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };
            handler.Proxy = null;
            HttpResponseMessage response;
            using (var myHttpClient = new HttpClient(handler))
            {
                myHttpClient.DefaultRequestHeaders.ExpectContinue = false;
                myHttpClient.DefaultRequestHeaders.Add("Accept-Charset", "ISO-8859-1,utf-8");
                myHttpClient.DefaultRequestHeaders.Add(APPKEY_HEADER, CustomHeaders.GetValues(APPKEY_HEADER));
                myHttpClient.DefaultRequestHeaders.Add(SESSION_TOKEN_HEADER, CustomHeaders.GetValues(SESSION_TOKEN_HEADER));
                myHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json-rpc"));
                var call = new JsonRequest { Method = method, Id = 1, Params = args };
                var jsonObject = JsonConvert.Serialize<JsonRequest>(call);
                var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json-rpc");
                response = await myHttpClient.PostAsync(new Uri(EndPoint), content);
            }
            Console.WriteLine("\nCalling: " + method + " With args: " + JsonConvert.Serialize<IDictionary<string, object>>(args));
            string jsonResponse = await response.Content.ReadAsStringAsync();

            return jsonResponse;
        }
    }


    public T Invoke<T>(string method, IDictionary<string, object> args = null)
    {
        if (method == null)
            throw new ArgumentNullException("method");
        if (method.Length == 0)
            throw new ArgumentException(null, "method");
        var jsonString = DoHttpClientPost(method, args).Result;
        var jsonResult = JsonConvert.Deserialize<JsonResponse<T>>(jsonString);

        return jsonResult.Result;
    }

【问题讨论】:

    标签: c# asynchronous httpclient


    【解决方案1】:
    var jsonString = DoHttpClientPost(method, args).Result;
    

    这是你的罪魁祸首。如果您从 UI 线程对 Task 调用 .Result,它将挂起。

    您需要一直异步 - 所以 Invoke 应该是异步的并返回一个 Task&lt;T&gt; 并等待 DoHttpClientPost 调用,调用者应该是异步等等等等。

    【讨论】:

    • 感谢您的帮助。
    【解决方案2】:

    你必须做出两个改变

    修改这一行

    response = await myHttpClient.PostAsync(new Uri(EndPoint), content);
    

    response = await myHttpClient.PostAsync(new Uri(EndPoint), content).ConfigureAwait(false);
    

    而且看起来你的意图是等待 post 调用完成并返回结果,所以从

    修改这一行
    var jsonString = DoHttpClientPost(method, args).Result;
    

    var jsonStringTask = DoHttpClientPost(method, args);
    jsonStringTask.Wait(); //wait for http post call to complete.
    
    var jsonString = jsonStringTask.Result;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多