我可以阻止MVC Core中的异步代码吗?

时间:2016-10-18 17:24:18

标签: c# async-await asp.net-core-mvc

我们都知道the famous blog post有关Stephen Cleary阻止异步代码的问题。在MVC 5中,请求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";
    }
}

但是,完全相同的代码在MVC Core Web应用程序中并不会死锁。响应返回 Hello 。为什么? MVC Core是否允许多个线程在一个请求上下文中同时运行?在MVC Core中开发时, 不要阻止异步代码 短语过时了吗?

2 个答案:

答案 0 :(得分:11)

  

为什么?

ASP.NET Core从上到下是async,它的设计旨在实现最高速度。

作为重新设计的一部分,ASP.NET团队能够完全删除整个AspNetSynchronizationContext。 ASP.NET请求上下文的某些方面已移至核心.NET,而其他方面则被删除(例如,HttpContext.Current)。

  

MVC Core是否允许多个线程在一个请求上下文中同时运行?

没有。 &#34;请求上下文的概念&#34;但是,不再用同步上下文表示。

  

在MVC Core中进行开发时,不在Async Code上的阻止语句是否过时了?

没有。它在ASP.NET Core上不会死锁,但你仍然不应该这样做。

&#34;我可以阻止MVC Core中的异步代码吗?&#34;是。 &#34;我应该阻止MVC Core中的异步代码吗?&#34;否。

答案 1 :(得分:2)

此代码

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

可能不是一个很好的模式,但它并不是&#34;阻止&#34;就像斯蒂芬的帖子所指的那样。要比较苹果和苹果,你必须这样做:

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

阻止Wait().Result是MVC 5的重要禁忌。据我所知,这仍然是对MVC Core的正确建议。