Controllori asincroni in ASP.NET MVC: Vantaggi reali / Come ottenuti?

11

Ho lavorato a un articolo sui metodi dei controller asincroni in ASP.NET MVC ( link ) e penso che possa mancare il punto.

Considera questo metodo che ho scritto, che è molto simile a un esempio tratto dall'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);
    }

Mentre capisco le cose, questo è il modo in cui le cose si svolgeranno in fase di runtime:

  1. Verrà creato un thread ASP.NET per una richiesta HTTP in entrata.

  2. Questo thread (presumibilmente avrà fatto un lavoro preliminare necessario) inserirà il mio metodo Index () sopra.

  3. L'esecuzione raggiungerà la parola chiave "await" e darà il via a un processo di acquisizione dati su un altro thread.

  4. Il thread "ASP.NET" originale tornerà al codice che ha chiamato il mio metodo handler, con un'istanza di classe Task come valore di ritorno.

  5. Il codice infrastrutturale che ha chiamato il mio metodo handler continuerà a funzionare sul thread "ASP.NET" originale, fino a raggiungere un punto in cui è necessario utilizzare l'oggetto ActionResult effettivo (ad esempio per eseguire il rendering della pagina).

  6. Il chiamante accederà quindi a questo oggetto usando il membro Task.Result, che lo farà (cioè il thread "ASP.NET") per attendere il thread creato implicitamente nel passaggio # 3 sopra.

Non vedo cosa comporti questo rispetto alla stessa cosa senza attendere / asincronizzare, tranne che per due cose che percepisco come insignificanti:

  • Il thread del chiamante e il thread di lavoro creati dall'attesa possono operare in parallelo per un certo periodo di tempo (la parte "fino a" del precedente # 5). La mia impressione è che il periodo di tempo sia piuttosto piccolo. Quando l'infrastruttura richiama un metodo di controllo, penso che in genere sia necessario l'effettivo ActionResult della chiamata del controller prima che possa fare molto (se mai) di più.

  • Esistono alcune nuove infrastrutture utili relative al timeout e all'annullamento delle operazioni con controller asincrono di lunga durata.

Lo scopo di aggiungere metodi di controller asincrono dovrebbe liberare quei thread di lavoro ASP.NET per rispondere effettivamente alle richieste HTTP. Questi thread sono una risorsa finita. Sfortunatamente, non vedo come il pattern suggerito nell'articolo serva effettivamente a conservare questi thread. E anche se lo fa, e in qualche modo scarica l'onere di gestire la richiesta su qualche thread non-ASP.NET, che cosa comporta? I thread che sono in grado di gestire una richiesta HTTP molto diversa dai thread in generale?

    
posta user1172763 18.03.2015 - 15:49
fonte

1 risposta

9

ASP.Net che non usa la Task Parallel Library (TPL) è limitato nel numero di richieste che può gestire contemporaneamente dal numero di thread in un pool di thread. ASP.Net che utilizza la TPL è limitato dalla CPU / memoria / I / O delle richieste di gestione macchina.

La Task Parallel Library (TPL) non consuma thread nel modo in cui sembra che pensi di farlo. I task non sono thread, sono un wrapper attorno ad alcune unità di calcolo. L'utilità di pianificazione è responsabile dell'esecuzione di ogni attività su qualsiasi thread non occupato. In fase di runtime, in attesa di un'attività non si blocca il thread, esso semplicemente parcheggia lo stato di esecuzione in modo che possa procedere in un secondo momento.

Normalmente, una singola richiesta HTTP viene gestita da un singolo thread, rimuovendo completamente quel thread dal pool finché non viene restituita una risposta. Con la TPL, non sei vincolato da questo vincolo. Qualsiasi richiesta che arriva inizia una continuazione con ogni unità di calcolo necessaria per calcolare una risposta in grado di eseguire su qualsiasi thread nel pool. Con questo modello, puoi gestire molte più richieste simultanee rispetto a ASP.Net standard.

    
risposta data 18.03.2015 - 16:58
fonte

Leggi altre domande sui tag