Quando realizziamo una Action asincrona all'interno di un controller, che magari esegue chiamate esterne e può avere una durata consistente, può essere opportuno stabilire un timeout a seguito del quale l'operazione debba essere annullata. Per questo scopo possiamo utilizzare l'attributo AsyncTimeout:
[AsyncTimeout(1000)] public async Task<ActionResult> Index(CancellationToken token) { var model = new MyModel(); model.FirstValue = await serviceClient.VeryLongOperationAsync(); model.SecondValue = await serviceClient.AnotherVeryLongOperationAsync(); return this.View(model); }
Nel codice in alto abbiamo impostato un timeout di 1 secondo per eseguire le due chiamate asincrone. Come possiamo notare, è necessario specificare come parametro della action un CancellationToken, che verrà utilizzato da ASP.NET per segnalarci l'eventuale scadenza del timeout.
Immaginiamo che la prima chiamata duri talmente tanto da superare da sola il tempo a disposizione. In questo caso, ASP.NET solleva una TimeoutException nella pipeline di risposta, e quindi non restituirà mai la View desiderata, sebbene l'esecuzione della action continuerà in ogni caso sino al suo termine. In questo caso, può essere sensato evitare chiamate inutili e terminarne l'esecuzione, verificando se è stata richiesta una cancellazione dell'operazione tramite il token:
[AsyncTimeout(1000)] public async Task<ActionResult> Index(CancellationToken token) { var model = new MyModel(); model.FirstValue = await serviceClient.VeryLongOperationAsync(); token.ThrowIfCancellationRequested(); model.SecondValue = await serviceClient.AnotherVeryLongOperationAsync(); token.ThrowIfCancellationRequested(); return this.View(model); }
Grazie a ThrowIfCancellationRequested, infatti, possiamo sollevare un'eccezione nel caso in cui l'operazione sia stata cancellata, interrompendo di fatto l'esecuzione del metodo del controller.
Per migliorare l'esperienza utente, possiamo eventualmente prevedere una pagina di errore apposita, per esempio utilizzando l'attributo HandleError sulla action:
[AsyncTimeout(100), HandleError(ExceptionType=typeof(TimeoutException), View="timeout")] public async Task<ActionResult> Index(CancellationToken token) { // .. codice qui .. }
Affinché funzioni, ovviamente, è necessario abilitare i custom error su web.config.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Utilizzare Tailwind CSS all'interno di React: installazione
Eseguire query manipolando liste di tipi semplici con Entity Framework Core
.NET Conference Italia 2024
Evitare il flickering dei componenti nel prerender di Blazor 8
Gestire il colore CSS con HWB
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Miglioramenti agli screen reader e al contrasto in Angular
Usare lo spread operator con i collection initializer in C#
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Registrare servizi multipli tramite chiavi in ASP.NET Core 8
Creare una libreria CSS universale: Cards