Question

I have a search action that has two paths, a synchronous path, that just returns a simple view, and a asynchronous path, that does the search asynchronously and then returns a view. Both are GET requests, so they are part of the same action.

The problem is that when I access the action "localhost:XXXX/Home/Search", the page just infinitely loads. Using Fiddler, I can see that the request never returns. I've debugged it and it makes it to the last line of code, but, again, the request doesn't complete.

I've simplified the repro to the following:

public async Task<ActionResult> Search() 
{ 
    return View(); 
} 

VS11 warns me that the code will be run synchronously without an await, which is fine, but the request doesn't complete.

Should this work? Or do I need to do something else here?

Edit

This is MVC 4 targeting .NET 4.5.

Edit 2

For those who see things better in code, this is why I need synchronous in an async action:

public async Task<ActionResult> Search(string query = null)
{
    if (string.IsNullOrWhiteSpace(query))
        return View(new SearchViewModel());   // never loads

    var model = await _someService.SearchAsync(query);
    return View(model);    // loads
}
Was it helpful?

Solution

This is a known bug in the beta. To quote Stephen Toub:

The short answer is that there is a known bug in ASP.NET MVC in the .NET 4.5 Beta that results in this issue when the async method completes synchronously. Until a fix is available, a simple workaround is to add "await Task.Yield();" as the first line of the async method, forcing it to complete asynchronously. For this to work correctly, you also need to ensure you're using the new SynchronizationContext supplied by ASP.NET in .NET 4.5, which means ensuring you have the line:

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

in the appSettings section of your configuration file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top