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
Ottimizzare la latenza in Blazor 8 tramite InteractiveAuto render mode
Generare token per autenicarsi sulle API di GitHub
Controllare gli accessi IP alle app con Azure Container Apps
Potenziare Azure AI Search con la ricerca vettoriale
Applicare il versioning ai nostri endpoint ASP.NET Core Minimal API
Usare lo spread operator con i collection initializer in C#
Creare moduli CSS in React
Eseguire un metodo asincrono dopo il set di una proprietà in Blazor 8
Migrare una service connection a workload identity federation in Azure DevOps
Usare una container image come runner di GitHub Actions
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Ottimizzazione dei block template in Angular 17