我们都知道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中开发时, 不要阻止异步代码 短语过时了吗?
答案 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的正确建议。