0

I have an async method that works when used with the .Result property, but not when using the await keyword. I thought using await instead of result was correct. Am I wrong?

// doesn't work - hangs
protected async Task<T> GetAsync<T>(string uri) =>
    await ParseJson<T>(await Client.GetAsync(uri));

// works
protected async Task<T> GetAsync<T>(string uri) =>
    await ParseJson<T>(Client.GetAsync(uri).Result);

The Client in the above code is a HttpClient, and the ParseJson method is as follows:

protected async Task<T> ParseJson<T>(HttpResponseMessage response) =>
    JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync(), Settings);

The code is being run in an asp.net mvc application if that makes any difference.

Update Fixed. Thanks to: @Igor - You were correct, the MVC controllor action calling the method was not asynchronous and was therefore using .Result instead of await. @Panagiotis - I've split my code out as you suggested to make it more debuggable.

Nick
  • 5,616
  • 10
  • 52
  • 72
  • Can you please share Client.GetAsync functions source? – Samvel Petrosov Mar 17 '17 at 10:52
  • 1
    Post code that can reproduce the problem. What you posted, once cleaned up, is the typical way of using HttpClient. For example, `ParseJson` isn't an asynchronous function, it simply mixes up `ReadAsStringAsync` with `Deserialize`. Your code would actually be cleaner if you *separated* the calls. At least this way you could debug the code and see *which* line blocks, if any – Panagiotis Kanavos Mar 17 '17 at 10:53
  • 1
    Typical call with HttpClient that *doesn't* block: `var response=await client.Get(uri); var text=await response.Content.ReadAsStringAsync();var myItem=JsonConvert.DeserializeObject(text,settings);`. That's what your code does, in a way that prevents actual debugging. – Panagiotis Kanavos Mar 17 '17 at 10:55
  • 3
    It is code you are not showing us, most likely you tried using `async/await` BUT one of the implementations not shown is using `.Result` (like the implementation of `Client.GetAsync(string)`, ie. code in that method). – Igor Mar 17 '17 at 10:55
  • 1
    PS You can get rid of `ParseJson` entirely. HttpClient allows you to use your own Json converter to deserialize objets. By default it uses the old JavascriptSerializer but you can instruct it to use Json.NET [as shown here](http://stackoverflow.com/questions/13915485/net-httpclient-with-custom-jsonconverter). Your code can be as simple as `var response=await client.GetAsync(uri); var myItem=await responce.Content.ReadAsAsync(formatter);` – Panagiotis Kanavos Mar 17 '17 at 11:01

0 Answers0