Ho lavorato su un articolo sui metodi del controller asincrono in ASP.NET MVC ( http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx ) e penso Forse mi manca il punto.
Considera questo metodo che ho scritto, che è molto simile a un esempio dell'articolo:
[HttpGet]
[AsyncTimeout(8000)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimedOut")]
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
WidgetPageViewModel model = new WidgetPageViewModel()
{
toAdd = new Widget()
};
model.all = await _repo.GetAllAsync(cancellationToken);
return View(model);
}
Come capisco le cose, questo è come le cose si svolgeranno in fase di esecuzione:
Verrà creato un thread ASP.NET per una richiesta HTTP in entrata.
Questo thread (presumibilmente fatto qualche lavoro preliminare necessario) entrerà nel mio metodo Index () sopra.
L'esecuzione raggiungerà la parola chiave "wait" e avvierà un processo di acquisizione dati su un altro thread.
Il thread "ASP.NET" originale tornerà al codice che chiamava il mio metodo handler, con un'istanza della classe Task come valore di ritorno.
Il codice infrastrutturale che ha chiamato il mio metodo handler continuerà a funzionare sul thread originale "ASP.NET", fino a quando non raggiunge un punto in cui deve utilizzare l'oggetto ActionResult effettivo (ad esempio per eseguire il rendering della pagina).
Il chiamante accederà quindi a questo oggetto utilizzando il membro Task.Result, che farà sì che esso (ovvero il thread "ASP.NET") attenda il thread creato implicitamente nel passaggio 3 sopra.
Non vedo ciò che questo compie rispetto alla stessa cosa senza attesa / asincrono, ad eccezione di due cose che percepisco insignificanti:
Il thread del chiamante e il thread di lavoro creati da waitit possono funzionare in parallelo per un certo periodo di tempo (la parte "fino a" del numero 5 sopra). La mia idea è che il periodo di tempo sia piuttosto piccolo. Quando l'infrastruttura chiama un metodo controller, penso che in genere abbia bisogno dell'effettivo ActionResult della chiamata controller prima che possa fare molto (se non altro) di più.
Esistono alcune nuove utili infrastrutture relative al timeout e alla cancellazione di operazioni di controller asincrone di lunga durata.
Lo scopo di aggiungere metodi del controller asincrono è quello di liberare quei thread di lavoro ASP.NET per rispondere effettivamente alle richieste HTTP. Questi thread sono una risorsa limitata. Sfortunatamente, non vedo come lo schema suggerito nell'articolo serva effettivamente a conservare questi thread. E anche se lo fa, e in qualche modo scarica l'onere della gestione della richiesta su un thread non-ASP.NET, cosa compie questo? I thread che sono in grado di gestire una richiesta HTTP sono molto diversi dai thread in generale?
Execution will reach the "await" keyword and kick off a data acquisition process on another thread
-- Non necessariamente.async
non richiede un altro thread ... È una continuazione. Può essere realizzato riordinando le istruzioni sullo stesso thread.