2014-06-23 3 views
5

Ich habe eine MVC-Controller-Aktion, die mehrere Webanforderungen stellen muss. So in einem Versuch, diesen Thread zu befreien anderen eingehenden Web-Anfragen zu behandeln, schrieb ich etwas wie folgt aus: (HINWEIS: dies eine starke Vereinfachung des realen Code)Hilft Task.Factory.StartNew in ASP.Net MVC?

public async Task<ViewResult> Index() 
{ 
    MyObj o = await Task.Factory.StartNew<MyObj>(() => 
    { 
     WebClient c = new WebClient(); 
     var res1 = c.DownloadString("..."); 
     var res2 = c.DownloadString("..."); //Not shown but res1 required for this call. 
     return new MyObj(res1, res2); 
    } 
    return View(o); 
} 

Meine Frage I haben Dinge gemacht besser oder schlechter, indem du einen neuen Thread drehst, um diese Arbeit zu erledigen. Meine Absicht ist, diesen .Net-Thread zu befreien, um andere eingehende Anfragen zu behandeln, während die Netzwerkanfragen gemacht werden. Aber nach dem Anschauen scheint mir, dass ich immer noch einen .Net-Thread-Block mache, nur vielleicht einen anderen als den Thread-Pool anstelle des Originals, also geht es mir wirklich nicht besser. Also ist mein Verdacht richtig und der obige Code macht die Dinge schlimmer?

Der Vorteil von Task.Factory.StartNew(), wenn es funktionierte ... ist, dass es die Arbeit darin vereinfacht, dass alles asynchron gemacht werden muss. Meine Frage ist jedoch: Wird auf diese Weise tatsächlich ein Thread für die Verarbeitung eingehender Webanfragen freigegeben oder bindet er immer noch dieselbe Anzahl von Threads aus dem Threadpool?

Antwort

4

Ja, Sie blockieren gerade einen anderen Thread.

Wenn das gut war, würde MVC alle Aktionsmethoden in einer neuen Aufgabe automatisch umbrechen.

Um die Threads zu entsperren, benötigen Sie asynchrone IO irgendwo unter den Abdeckungen. Die BCL stellt dies normalerweise bereit. Wenn auf der Box "async" steht, handelt es sich normalerweise um async IO.

Das heißt, nur wenige Web-Anwendungen haben das Problem, dass die Threads ausgehen. Der Thread-Pool startet bei Bedarf Tonnen von Threads. Sehr wenige Web-Apps sind im Durchsatz durch die Anzahl der verfügbaren Threads begrenzt. Müssen Sie wirklich 100 gleichzeitige Anfragen verarbeiten? Können Ihre Back-End-Dienste diese Last sogar verarbeiten? Wenn eine dieser Fragen mit "Nein" beantwortet wird, benötigen Sie kein Async.

+0

Vielen Dank, es macht Sinn, dass Sie Bausteine ​​auf niedriger Ebene benötigen, um echte asynchrone Methoden zu erstellen, die keinen .net-Thread verwenden. – user3766657

1

Sie müssen nicht den Fabrikblock.

public async Task<ViewResult> Index() 
{ 
    WebClient client = new WebClient(); 
    var result1 = await client.DownloadStringAsync("..."); 
    var result2 = await client.DownloadStringAsync("..."); 

    /* whatever you're doing with result1 & result2 */  

    return View(); 
} 
+0

Mein Beispiel ist vereinfacht, weil die reale Sache unnötig komplex ist, um die Frage zu demonstrieren. Der Vorteil von Task.Factory.StartNew(), wenn es funktionierte ... ist, dass es die Arbeit innerhalb von async vereinfacht. Meine Frage ist jedoch, ob es tatsächlich einen Thread für die Bearbeitung von Web-Anfragen freigibt oder ob er immer noch die gleiche Anzahl von Threads aus dem Thread-Pool bindet. – user3766657

2

Der Code, den Sie ist nicht wirklich optimal gemacht, da beide lange Operationen gegenseitig blockieren: Sie können Ihr Beispiel vereinfachen

var result1 = c.DownloadString("..."); 

läuft zuerst und wenn Sie fertig sind, läuft es

var result2 = c.DownloadString("..."); 

Das Hinzufügen eines zusätzlichen Threads, in dem dieser ausgeführt wird, verbessert die Leistung nicht und es werden keine offenen Anforderungen freigegeben.

+0

Es wird nicht angezeigt, aber sie müssen seriell ausgeführt werden, da der zweite Webaufruf von den Ergebnissen des ersten abhängt. Aber das ist wirklich nicht die Frage, die ich stelle. – user3766657

+0

Wenn sie voneinander abhängig sind, besteht keine Notwendigkeit, einen zusätzlichen Thread zu erstellen. Dies wird dir dann in keiner Weise helfen. –

+0

Ich glaube, du täuschst dich. Das Ziel ist nicht die Parallelisierung, es erhöht die Anzahl gleichzeitiger Anfragen, die Sie verarbeiten können. – user3766657