2016-11-30 50 views
1

我想发送一个http帖子,可能需要几秒钟的回复而不冻结我的用户界面,目前这个代码只是挂起我的应用程序,当方法被调用。C#HttpClient POST'ing异步

我在做什么错,我如何实现我的目标?

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; 
    } 

回答

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

这是您的罪魁祸首。如果您在UI线程的任务上致电.Result,它将挂起。

你需要异步了所有的办法 - Invoke应该是异步和返回Task<T>伺机DoHttpClientPost呼叫,主叫方应异步等等,等等等等

+0

谢谢您的帮助。 – itsdrea

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;