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
Eseguire query manipolando liste di tipi semplici con Entity Framework Core
Sfruttare MQTT in cloud e in edge con Azure Event Grid
Eseguire una query su SQL Azure tramite un workflow di GitHub
Introduzione alle Container Queries
Sostituire la GitHub Action di login su private registry
Evitare il flickering dei componenti nel prerender di Blazor 8
C# 12: Cosa c'è di nuovo e interessante
Eseguire una ricerca avanzata per recuperare le issue di GitHub
Esporre i propri servizi applicativi con Semantic Kernel e ASP.NET Web API
Disabilitare automaticamente un workflow di GitHub (parte 2)
Escludere alcuni file da GitHub Secret Scanning
Supportare il sorting di dati tabellari in Blazor con QuickGrid
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- .NET Conference Italia 2023 - Milano e Online
- .NET Conference Italia 2024 - Milano
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!