2016-11-30 51 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;