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
Ottimizzazione dei block template in Angular 17
Sfruttare MQTT in cloud e in edge con Azure Event Grid
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
Cambiare la chiave di partizionamento di Azure Cosmos DB
Simulare Azure Cosmos DB in locale con Docker
Migliorare i tempi di risposta di GPT tramite lo streaming endpoint in ASP.NET Core
Gestire gli accessi con Token su Azure Container Registry
Eliminare una project wiki di Azure DevOps
Hosting di componenti WebAssembly in un'applicazione Blazor static
Migliorare la scalabilità delle Azure Function con il Flex Consumption
Filtrare i dati di una QuickGrid in Blazor con una drop down list
Autenticarsi in modo sicuro su Azure tramite GitHub Actions