In uno script precedente (https://www.aspitalia.com/script/1459/Sfruttare-Streaming-Chiamata-HTTP-Blazor.aspx) ci siamo occupati del concetto di streaming tra Blazor e ASP.NET Core, e abbiamo visto come può essere una soluzione molto interessante quando si tratta di inviare corpose moli di dati dal server al client.
Tuttavia, in questi contesti, vogliamo anche supportare la cancellazione della richiesta. Immaginiamo per esempio, di trovarci sulla pagina che invia la richiesta HTTP in streaming. Nel momento in cui navighiamo via dalla pagina corrente, se proviamo a guardare il network inspector del browser, noteremo un comportamento inaspettato: la richiesta HTTP, non essendo ancora terminata, continuerà a funzionare in background, usando risorse sia sul server che sul client per un risultato che non verrà mai visualizzato all'utente.
Si tratta di un comportamento poco corretto, e il modo per evitarlo è quello di sfruttare un CancellationToken. Il primo passo è ovviamente quello di aggiungere questa funzionalità al nostro extension method GetAsyncEnumerable:
public static class HttpExtensions { public async static IAsyncEnumerable<T> GetAsyncEnumerable<T>(this HttpClient http, string url, CancellationToken token = default) // <-- cancellation token passato dall'esterno { using var request = new HttpRequestMessage(HttpMethod.Get, url); request.SetBrowserResponseStreamingEnabled(true); // passiamo il cancellation token alla richiesta... using var response = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token)); response.EnsureSuccessStatusCode(); // ... alla lettura dello stream ... using var responseStream = await response.Content.ReadAsStreamAsync(token); // ... e alla sua deserializzazione ... IAsyncEnumerable<T> items = JsonSerializer.DeserializeAsyncEnumerable<T>(responseStream, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, DefaultBufferSize = 128 }); await foreach (T item in items) { yield return item; } } }
Come possiamo notare, tutto ciò che dobbiamo fare è aggiungere un parametro di tipo CancellationToken e passarlo ai vari statement asincroni che dobbiamo eseguire.
A questo punto, dobbiamo fare in modo che venga invocato quando navighiamo via dalla pagina corrente. La soluzione è implementare l'interfaccia IDisposable come mostrato in basso:
@page "/fetchdata" @implements IDisposable ... altro codice qui ... @code { private CancellationTokenSource _cts = new(); // .. altro codice qui .. protected override async Task OnInitializedAsync() { var results = Http.GetAsyncEnumerable<WeatherForecast>("https://localhost...", _cts.Token); // ... altro codice qui ... } public void Dispose() { _cts.Cancel(); } }
La pagina contiene un field di tipo CancellationTokenSource, che usiamo per inviare il token alla chiamata GetAsyncEnumerable. Nel metodo Dispose, ne invochiamo il Cancel, così da segnalare che non è più necessario proseguire nella richiesta. Questo farà sì che la chiamata HTTP venga correttamente terminata, sia sul client, sia sul server, visto che ASP.NET Core gestisce automaticamente la cancellazione della richiesta terminandone l'esecuzione.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Hosting di componenti WebAssembly in un'applicazione Blazor static
Reactive form tipizzati con FormBuilder in Angular
Eseguire query verso tipi non mappati in Entity Framework Core
.NET, Serilog e SEQ - un buon trio per loggare facilmente
Creare gruppi di client per Event Grid MQTT
Eseguire operazioni sui blob con Azure Storage Actions
Generare velocemente pagine CRUD in Blazor con QuickGrid
Eseguire query manipolando le liste contenute in un oggetto mappato verso una colonna JSON
Rinnovare il token di una GitHub App durante l'esecuzione di un workflow
Aprire una finestra di dialogo per selezionare una directory in WPF e .NET 8
Limitare le richieste lato server con l'interactive routing di Blazor 8
Come EF 8 ha ottimizzato le query che usano il metodo Contains
I più letti di oggi
- anche domani dalle 17:30 seguite con noi live #build15 https://aspit.co/build15
- Webcast 'AJAX & ATLAS Overview'
- a #igds il 25 e 26/10 a Milano puoi sviluppare un gioco per #wp8 con @AppCampus. in palio 70.000 Euro: https://aspit.co/apa
- WinJS in Windows Phone 8.1
- la RC di #vs13 è compatibile con #win81 RTM, non con la Preview. l'annuncio ufficiale è su https://aspit.co/any
- Ancora un bug: esce Mono 0.23
- SSL Certificates for everyone on Azure
- Mostrare una MessageBox con un custom control
- disponibile la preview 1 ci #dotnetcore 2.1, #aspnetcore, #efcore. performance, novità e migliorie su https://aspit.co/bmf
- si continua a #netconfit con 'developing modern web apps with #aspnetcore', con il nostro @dbochicchiohttps://aspit.co/netconf-18