C#HttpClient POST'ing Async

时间:2016-11-30 02:31:10

标签: c# asynchronous httpclient

我想发送一个可能需要几秒钟才能回复而不冻结我的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;
    }

2 个答案:

答案 0 :(得分:3)

var jsonString = DoHttpClientPost(method, args).Result;

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

你需要一直异步 - 所以Invoke应该是异步并返回Task<T>并等待DoHttpClientPost调用,调用者应该是异步等等。等

答案 1 :(得分:0)

您必须进行两项更改

修改此行
response = await myHttpClient.PostAsync(new Uri(EndPoint), content);

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

看起来你的目的是等待帖子调用完成并返回结果,所以从

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

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

var jsonString = jsonStringTask.Result;