In uno script precedente (https://www.aspitalia.com/script/1396/Eseguire-Task-Temporizzati-Tramite-Hosted-Service-ASP.NET-Core.aspx) abbiamo introdotto il funzionamento degli HostedService di ASP.NET Core per quanto riguarda l'esecuzione di task temporizzati.
Tra le varie cose, abbiamo visto che il metodo StartAsync riceve come parametro un CancellationToken, che viene utilizzato dal runtime per segnalare lo spegnimento dell'applicazione durante la fase di avvio del nostro servizio.
Il problema è che, una volta che il servizio è avviato, il token non viene più utilizzato, e l'eventuale shutdown ci verrà notificato solo tramite una chiamata a StopAsync. In corrispondenza di questa chiamata, però, vorremmo comunque poter interrompere eventuali operazioni lunghe in maniera corretta.
Per farlo, possiamo creare un CancellationTokenSource e invocarne la cancellazione in fase di StopAsync:
private CancellationTokenSource _tokenSource; public Task StartAsync(CancellationToken cancellationToken) { _tokenSource = new CancellationTokenSource(); _timer = new Timer(async s => { try { Console.WriteLine("Starting long operation"); await LongOperationAsync(_tokenSource.Token); Console.WriteLine("Long operation completed"); } catch (OperationCanceledException) { Console.WriteLine("Long operation cancelled"); } }, null, TimeSpan.Zero, TimeSpan.FromSeconds(30)); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _timer.Change(Timeout.Infinite, Timeout.Infinite); _tokenSource.Cancel(); return Task.CompletedTask; }
Nell'esempio in alto, istanziamo il CancellationTokenSource come prima operazione in fase di StartAsync. Successivamente, passeremo il suo token a ogni operazione che lo preveda. Il nostro codice esegue questa logica all'interno di un blocco Try..Catch per gestire anche la casistica in cui il componente invocato sollevi una OperationCanceledException, che è il tipo di eccezione generata dalla chiamata al metodo ThrowIfCancellationRequested di CancellationToken.
In fase di StopAsync, come già accennato, ci limitiamo invece a chiamare il metodo Cancel del nostro CancellationTokenSource, così da segnalare a tutti i suoi utilizzatori la volontà di terminare eventuali task in corso.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
-
Limitare le richieste lato server con l'interactive routing di Blazor 8
-
Evitare la command injection in un workflow di GitHub
-
Usare un KeyedService di default in ASP.NET Core 8
-
Configurare dependabot per aggiornare le dipendenze di terze parti con GitHub Actions
-
Effettuare il download di un file via FTP con la libreria FluentFTP di .NET
-
Determinare lo stato di un pod in Kubernetes
-
Reactive form tipizzati con FormBuilder in Angular
-
Utilizzare database e servizi con gli add-on di Container App
-
Miglioramenti agli screen reader e al contrasto in Angular
-
Utilizzare un service principal per accedere a Azure Container Registry
-
Creare form tipizzati con Angular
-
Eseguire operazioni sui blob con Azure Storage Actions
I più letti di oggi
- Evitare il flickering dei componenti nel prerender di Blazor 8
- Rilasciata la Beta 2 di Visual Studio 2008
- tra pochi minuti inizia la keynote della seconda giornata. seguila live su http://aspitalia.com/mix-11 #mix11
- .@dbochicchio ora su #aspnetcore 2 a #netconfit https://aspit.co/netconf-17
- Utilizzare angular-cli per creare una direttiva in Angular 2
- Windows Vista: il ritorno di WinFS con la beta1
- .@CristianCivera tra poco su #azure con i suoi tips&tricks per lo sviluppatore web: https://aspit.co/web15-live #aspilive
- Le novità di C# 10