itsdrea
itsdrea

Reputation: 11

C# HttpClient POST'ing Async

I want to send a http post that can take a couple of seconds to reply without freezing my UI, currently this code just hangs my application when the method is callled.

What am I doing wrong and how do i achieve my goal?

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

Upvotes: 1

Views: 1566

Answers (2)

Vinod
Vinod

Reputation: 1952

You have to make two changes

Modify this line from

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

to

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

And looks like your intention is to wait for the post call to complete and return the results, so modify this line from

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

to

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

var jsonString = jsonStringTask.Result;

Upvotes: 0

JimBobBennett
JimBobBennett

Reputation: 2159

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

This is your culprit. If you call .Result on a Task from the UI thread it will hang.

You'll need to async all the way up - so Invoke should be async and return a Task<T> and await the DoHttpClientPost call, the caller should be async etc. etc. etc.

Upvotes: 3

Related Questions