0

I'm executing an async POST request using a HttpClient in C#/Xamarin:

private async Task<string> ServicePostRequest (string url, string parameters)
    {
        string result = String.Empty;

        using (var client = new HttpClient()) {
            HttpContent content = new StringContent (parameters);
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue ("application/x-www-form-urlencoded");
            client.Timeout = new TimeSpan (0, 0, 15);
            using(var response = await client.PostAsync(url, content)){
                using (var responseContent = response.Content) {
                    result = await responseContent.ReadAsStringAsync ();
                    Console.WriteLine (result);
                    return result;
                }
            }
        }
    }

When I execute the following code, the expected result (JSON) is being logged correctly in the terminal:

Task<string> result = ServicePostRequest("http://www.url.com", "parameters");

Now, I would like to get this result into a variable to be able to parse it. However, when I use the following code, no result is being logged at all and the application is frozen:

Task<string> result = ServicePostRequest("http://www.url.com", "parameters");
string myResult = result.Result;

Also when I use the result.Wait() method, the application doesn't respond at all.

Any help would be highly appreciated.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
Tomzie
  • 1,338
  • 4
  • 19
  • 25
  • 2
    The synchronization context is deadlocking when you call `.Result`. (See Stephen Cleary's links here: http://stackoverflow.com/questions/17248680/await-works-but-calling-task-result-hangs-deadlocks) Why can't you simply `await` the task like normal? – David Jun 29 '15 at 13:46
  • There is no need for this: using (var responseContent = response.Content) - you are not creating anything new here what needs to be disposed intependently, there is "using" around your response, that is enough. Just do: var responseContent = await response.Content.ReadAsStringAsync(); – rouen Jun 29 '15 at 13:58
  • Make sure that the whole pipeline is fully async. Calling async code from a synchronous method can cause deadlocks, if not dealt correctly. And use await on the task call – Chris Jun 29 '15 at 13:58

1 Answers1

1

Since ServicePostRequest is an awaitable method, change this:

Task<string> result = ServicePostRequest("http://www.url.com", "parameters");
string myResult = result.Result;

To:

 string result = await ServicePostRequest("http://www.url.com", "parameters");

Side Note: Make sure the calling method is an Asynchronous method.

Oluwafemi
  • 14,243
  • 11
  • 43
  • 59
  • I'm trying to use the await but it is giving me a parse error saying that the await can only be used when its containing method is marked with the async modifier. I double checked it already, and the ServicePostRequest method definitely has the async modifier. Any thoughts? – Tomzie Jun 29 '15 at 14:20
  • convert the calling method to an asynchronous method. – Oluwafemi Jun 29 '15 at 14:26