2016-11-30 2 views
1

Я хочу отправить сообщение http, которое может занять пару секунд, чтобы ответить, не замораживая мой пользовательский интерфейс, в настоящее время этот код просто зависает мое приложение при вызове метода.C# HttpClient POST'ing Async

Что я делаю неправильно и как достичь своей цели?

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; 

Это ваш виновник. Если вы вызываете .Result на задание из потока пользовательского интерфейса, он будет висеть.

Вам нужно ASync всего пути - так 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; 
Смежные вопросы