Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async method does not return asp.net mvc 4

I'm having a problem with an async method that I implemented. The method basically makes a HttpRequest to a resource and deserializes the string if the request is successful. I wrote a test for the method, and it works. But the method does never return when I call it from a controller?

    public async Task<IEnumerable<T>> Get()
    {
        try
        {
            var resourceSegmentUri = new Uri(_uri, UriKind.Relative);

            var response = await _client.GetAsync(resourceSegmentUri);

            if (response.IsSuccessStatusCode)
            {
                var submission = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<IEnumerable<T>>(submission);
            }

            if (response.Content != null)
            {
                var message = response.Content.ReadAsStringAsync();
                throw new WebException(message.Result, (WebExceptionStatus)response.StatusCode);
            }

        }
        catch (WebException e)
        {
            Logger.Error("GET Request failed with status: {0}", e.Status);
            throw;
        }

        throw new Exception();
    }

Code that never returns:

public ActionResult Index()
{
   var api = new Api();
   var test = api.Get().Result; //Never returns
   return View();
}

Test that works:

[Test]
public void GetShouldReturnIfSuccessfulRequest()
{
    var api = new Api();
    var submission = api.Get();

    Console.WriteLine(JsonConvert.SerializeObject(submission));
    Assert.NotNull(submission);
}

Does anyone know the problem?

like image 733
Bj Blazkowicz Avatar asked Apr 16 '13 10:04

Bj Blazkowicz


People also ask

What happens when async method is not awaited?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Can async method have return value?

Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.

How do I return an ActionResult task?

The return type of Task<ActionResult> represents ongoing work and provides callers of the method with a handle through which to wait for the asynchronous operation's completion. In this case, the caller is the web service. Task<ActionResult> represents ongoing work with a result of ActionResult.


1 Answers

You've got a deadlock because you're calling .Result in your controller action.

If you use async/await then you have to use asynchronous actions too.

So something like this should fix it:

public async Task<ActionResult> Index()
{
  var api = new Api();
  var test = await api.Get(); // Should return
}

There's a comprehensive article about this here: Using Asynchronous Methods in ASP.NET MVC 4

like image 160
Nick Butler Avatar answered Oct 22 '22 01:10

Nick Butler