2016-10-18 48 views
11

我們都知道the famous blog post關於由Stephen Cleary封鎖異步代碼。在MVC 5下面的代碼死鎖請求Home/Index時:我可以阻止MVC Core中的異步代碼嗎?

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核心的Web應用程序死鎖。回覆返回您好。爲什麼? MVC Core是否允許多個線程在一個請求上下文中同時運行? 請勿在異步代碼上阻塞在MVC Core中進行開發時,語句是否過時?

回答

9

爲什麼?

ASP.NET Core從上到下是async,它的設計目的是爲了獲得最高速度。

作爲重新設計的一部分,ASP.NET團隊能夠完全刪除整個AspNetSynchronizationContext。 ASP.NET請求上下文的某些方面已被移入核心.NET,而其他方面則被刪除(例如,HttpContext.Current)。

MVC Core是否允許多個線程在一個請求上下文中同時運行?

不是。「請求上下文」的概念不再由同步上下文表示。

當在MVC Core中開發時,異步代碼短語是否過時?

不會。它不會在ASP.NET Core上發生死鎖,但您仍然不應該這樣做。

「我可以阻止MVC Core中的異步代碼嗎?」是。 「我應該阻止MVC Core中的異步代碼嗎?」編號

+0

謝謝!我可以再次和平地編碼:-) – Kapol

2

此代碼

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

可能不是一個大格局,但在斯蒂芬的職位是指相同的意義上,它不是「堵」。要比較蘋果蘋果,你必須這樣做:

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

阻塞上Wait().Result是很大的禁忌爲MVC 5.據我所知,這仍然是正確的MVC核心的建議。

+0

您的示例在MVC Core中沒有死鎖。我仍然收到「Hello」 – Kapol

+0

@Kapol block!=死鎖。阻塞是指同步等待操作的結果。在異步操作中同步阻塞(例如,使用'Wait()')時會發生死鎖。需要注意的是,即使模式不正確(通過異步同步),死鎖也不會總是**發生。 –

+0

對不起,內特,當然我的意思是死鎖。就我所知,我的例子* always *導致了MVC 5中的死鎖,而我無法在MVC Core中至少重現一次這種行爲。 – Kapol

相關問題