Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I block on async code in MVC Core?

We all know the famous blog post regarding blocking on async code by Stephen Cleary. In MVC 5 the following code deadlocks when requesting Home/Index:

public class HomeController : Controller
{
    public string Index()
    {
        var model = AsyncMethod();
        return model.Result;
    }

    private async Task<string> AsyncMethod()
    {
        await Task.Run(() => Thread.Sleep(2000));
        return "Hello";
    }
}

However, the exact same code doesn't deadlock in an MVC Core web application. The response returns Hello. Why? Does MVC Core allow multiple threads to run simultaneously within one request context? Is the Don't Block on Async Code phrase out of date when developing in MVC Core?

like image 936
Kapol Avatar asked Oct 18 '16 17:10

Kapol


2 Answers

Why?

ASP.NET Core is async from top to bottom, and it's designed for maximum speed.

As part of the redesign, the ASP.NET team was able to remove the entire AspNetSynchronizationContext completely. Some aspects of the ASP.NET request context were moved into the core .NET, and others were just dropped (e.g., HttpContext.Current).

Does MVC Core allow multiple threads to run simultaneously within one request context?

No. The notion of a "request context" is no longer represented by a synchronization context, though.

Is the Don't Block on Async Code phrase out of date when developing in MVC Core?

No. It won't deadlock on ASP.NET Core, but you still shouldn't do it.

"Can I block on async code in MVC Core?" Yes. "Should I block on async code in MVC Core?" No.

like image 195
Stephen Cleary Avatar answered Oct 11 '22 14:10

Stephen Cleary


This code

await Task.Run(() => Thread.Sleep(2000));

might not be a great pattern, but it's not "blocking" in the same sense that Stephen's post refers to. To compare apples to apples, you'd have to do this:

private string BlockingAsyncMethod()
{
    Task.Run(() => Thread.Sleep(2000)).Wait();
    return "Hello";
}

Blocking on Wait() or .Result is the big no-no for MVC 5. To my knowledge, that is still correct advice for MVC Core.

like image 26
Nate Barbettini Avatar answered Oct 11 '22 14:10

Nate Barbettini