5

Ich verwende MVC4 ApiController, um Daten in Azure Blob hochzuladen. Hier ist der Beispielcode:Verwenden Sie Task.Factory.StartNew in MVC 4 async ApiController?

public Task PostAsync(int id) 
{ 
    return Task.Factory.StartNew(() => 
    { 
     // CloudBlob.UploadFromStream(stream); 
    }); 
} 

Macht dieser Code überhaupt Sinn? Ich denke, dass ASP.NET die Anfrage bereits in einem Worker-Thread verarbeitet. Daher scheint UploadFromStream in einem anderen Thread nicht sinnvoll zu sein, da es jetzt zwei Threads zum Ausführen dieser Methode verwendet (ich nehme an, dass der ursprüngliche Worker-Thread auf diesen UploadFromStream wartet) zu beenden?)

Also mein Verständnis ist, dass asynchrone ApiController nur sinnvoll ist, wenn wir einige integrierte asynchrone Methoden wie HttpClient.GetAsync oder SqlCommand.ExecuteReaderAsync verwenden. Diese Methoden verwenden wahrscheinlich intern E/A-Vervollständigungs-Ports, um den Thread während der eigentlichen Arbeit freizugeben. Also sollte ich den Code ändern?

public Task PostAsync(int id) 
{ 
    // only to show it's using the proper async version of the method. 
    return TaskFactory.FromAsync(BeginUploadFromStream, EndUploadFromStream...) 
} 

Auf der anderen Seite, wenn die ganze Arbeit in der Methode Post ist CPU/Speicher-intensive, dann wird die Asynchron-Version PostAsync nicht Durchsatz von Anforderungen helfen. Es könnte besser sein, einfach die normale Methode "public void Post (int id)" zu verwenden, richtig?

Ich weiß, es ist eine Menge Fragen. Hoffentlich wird es mein Verständnis der asynchronen Verwendung in der ASP.NET MVC klären. Vielen Dank.

Antwort

1

Ja, das meiste von dem, was Sie sagen, ist korrekt. Auch bis auf die Details mit Completion-Ports und so.

Hier ist ein winziger Fehler:

I assume the original worker thread is waiting for this UploadFromStream to finish?

Nur Ihre Aufgabe Thread ausgeführt wird. Sie verwenden schließlich die asynchrone Pipeline. Es wartet nicht auf das Ende der Aufgabe, es schließt nur eine Fortsetzung an. (Genau wie mit HttpClient.GetAsync).