2016-10-18 8 views
11

Wir alle wissen the famous blog post über das Blockieren auf Async-Code von Stephen Cleary. In MVC 5 der folgenden Code Deadlocks bei der Anforderung von Home/Index:Kann ich Async-Code in MVC Core blockieren?

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"; 
    } 
} 

jedoch genau den gleichen Code nicht in einer MVC-Core-Web-Anwendung ist eine Sackgasse. Die Antwort gibt Hello zurück. Warum? Ermöglicht MVC Core die gleichzeitige Ausführung mehrerer Threads in einem Anforderungskontext? Ist die nicht auf Async-Code Satz veraltet, wenn Sie in MVC Core entwickeln?

Antwort

9

Warum?

ASP.NET Core ist async von oben nach unten, und es ist für maximale Geschwindigkeit ausgelegt. Im Rahmen des Redesigns konnte das ASP.NET-Team die gesamte AspNetSynchronizationContext vollständig entfernen. Einige Aspekte des ASP.NET-Anforderungskontexts wurden in den Kern .NET verschoben und andere wurden einfach gelöscht (z. B. HttpContext.Current).

erlaubt MVC Kern mehrere Threads gleichzeitig innerhalb eines Anforderungskontext zu laufen?

Nein. Der Begriff "Anforderungskontext" wird jedoch nicht mehr durch einen Synchronisationskontext repräsentiert.

Ist die Option Nicht bei asynchronem Code blockieren bei der Entwicklung in MVC Core veraltet?

Nein. Es wird nicht auf ASP.NET Core Deadlock, aber Sie sollten es immer noch nicht tun.

"Kann ich asynchronen Code in MVC Core blockieren?" Ja. "Sollte ich den asynchronen Code in MVC Core blockieren?" Nr.

+0

Vielen Dank! Ich kann wieder friedlich codieren :-) – Kapol

2

Dieser Code

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

vielleicht kein großes Muster sein, aber es im gleichen Sinne, dass Stephen Beitrag bezieht sich auf „Blockieren“ nicht. So vergleichen Sie Äpfel mit Äpfeln, dann würden Sie haben, dies zu tun:

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

Blocking auf Wait() oder .Result ist die große no-no für MVC 5. Meines Wissens das ist immer noch richtige Beratung für MVC-Core.

+0

Ihr Beispiel nicht in MVC Core Deadlock. Ich bekomme immer noch "Hallo" – Kapol

+0

@Kapol Block! = Deadlock. Blockieren bezieht sich auf synchrones Warten auf das Ergebnis einer Operation. Deadlocks treten manchmal auf, wenn Sie bei einer asynchronen Operation synchron (z. B. mit 'Wait()') blockieren. Es ist wichtig zu beachten, dass selbst bei einem schlechten Muster (Synchronisierung über Async) Deadlocks nicht immer ** auftreten. –

+0

Entschuldigung, Nate, natürlich meinte ich Deadlock. Die Sache ist, soweit ich weiß, dass mein Beispiel * immer * zu einem Deadlock in MVC 5 führte, während ich dieses Verhalten nicht mindestens einmal in MVC Core reproduzieren kann. – Kapol

Verwandte Themen