Blazor Cancellation Token | C# Performance Optimierung

Blazor Cancellation Token: Performance-Tuning und UX-Verbesserung
Darius S. | Softwareentwickler
10/2024

TL;DR

Cancellation Tokens ermöglichen es in Blazor und C#, laufende asynchrone HTTP-Requests gezielt abzubrechen. Das verbessert die Performance, reduziert unnötige API-Aufrufe und sorgt für eine reaktionsschnelle Benutzeroberfläche – besonders bei Suchfeldern oder häufigen Eingaben.

Cancellation Token für Performance Optimierung in Blazor mit C#.

Bei Webanwendungen – insbesondere in Blazor-Anwendungen – und überall dort, wo HTTP-Requests gesendet werden, wird asynchrone Programmierung eingesetzt, wobei der gezielte Einsatz von Cancellation Tokens in C# eine wichtige Rolle bei der Performance-Optimierung spielt. Diese bietet zahlreiche Vorteile, wie eine flüssige Benutzeroberfläche, verbesserte Performance und parallele Zugriffe auf WebAPIs. Wenn man mit C# asynchron programmiert, stößt man früher oder später auf die Parameter asynchroner Funktionen, insbesondere auf das Cancellation Token. Die Idee dahinter ist einfach: Wenn eine asynchrone Methode ein Cancellation Token übergeben bekommt, kann die Ausführung der Methode vorzeitig abgebrochen werden.

Wofür wird ein Cancellation Token verwendet?

Ein einfaches Szenario ist ein Suchfeld mit einer großen Datenmenge. Der Benutzer gibt eine Zeichenfolge in das Suchfeld ein, und bei jedem neuen Buchstaben wird die Suche erneut durchgeführt. Ohne Cancellation Token wird jede Suche vollständig ausgeführt. Tippt ein Benutzer ein Wort, werden Suchergebnisse der einzelnen Buchstabenfragmente angezeigt, bevor das endgültige Suchergebnis vorliegt. Bei einfachen Suchanfragen wird zumindest die Wartezeit nicht maßgeblich beeinträchtigt. Wenn jedoch komplexe Berechnungen erforderlich sind, würden diese für jeden Buchstaben durchgeführt werden. In solchen Fällen kann ein Cancellation Token zu einer deutlichen Performance-Verbesserung führen.

Die Anwendung von Cancellation Tokens möchte ich an einem kleinen Beispiel verdeutlichen. Das Projekt ist hier zu finden:
GitHub: CancellationToken C# Blazor Demo

In diesem Szenario wurde eine Blazor-Webanwendung mit WebAPI entwickelt. Als Beispiel dient die Standard-‘Weather Forecast‘-Seite der Blazor-Vorlage. In der WebAPI wurde ein Controller hinzugefügt, der nach einer Verzögerung zufällige Wetterdaten zurückgibt. Der Zugriff auf die WebAPI erfolgt über einen Proxy (WeatherForecastProxy). Controller und Proxy implementieren beide das zugehörige Interface (IWeatherForecastExchange).

Dieser Programmfluss wurde zweimal implementiert: einmal ohne und einmal mit Cancellation Token. So können beide Szenarien, sowohl auf der Quellcode- als auch auf der Anwenderseite, miteinander verglichen werden.

Auf der Demo-‘Weather Forecast‘-Seite wurde ein Texteingabefeld hinzugefügt, welches auf das oninput-Blazor-Event reagiert. Wenn der Eingabetext geändert wird, soll von der API ein neuer zufälliger Wetterdatensatz abgerufen werden. In der Komponente Weather.razor (ohne Cancellation Token) wird über den Proxy jeweils ein Request gesendet, und entsprechend ändern sich die Daten im Frontend.

Um mit Cancellation Tokens zu arbeiten, benötigen wir in C# ein Objekt vom Typ CancellationTokenSource. In der textChanged-Methode der Komponente WeatherWithCancellation.razor wird der Token des vorherigen Aufrufs abgebrochen und eine neue CancellationTokenSource erstellt, deren Token an den Proxy übergeben wird.

Aufruf des Proxys mit Cancellation Token

1@code {
2    private List<WeatherForecastDTO>? forecasts;
3
4    private CancellationTokenSource _cts = new CancellationTokenSource();
5
6    protected override async Task OnInitializedAsync()
7    {
8        forecasts = await weatherForecastExchange.GetAll(DateTime.Now, _cts.Token);
9    }
10
11    private async Task textChanged(ChangeEventArgs e)
12    {
13        _cts.Cancel();
14        _cts = new CancellationTokenSource();
15        try
16        {
17            forecasts = await weatherForecastExchange.GetAll(DateTime.Now, _cts.Token);
18        }
19        catch (TaskCanceledException ex)
20        {
21            Console.WriteLine($"Task Canceled: {ex.Message}");
22        }
23        catch (Exception ex)
24        {
25            Console.WriteLine(ex.Message);
26        }
27    }
28}

Damit auf ein Cancellation Token reagiert werden kann, muss es in jede aufgerufene asynchrone Methode weitergegeben werden. Dementsprechend wird im Proxy und auch im Controller das Cancellation Token an die Service-Klasse, welche die Wetterdaten ermittelt, weitergereicht.

Proxy-Methode (Übergabe des Cancellation Tokens)

1public async Task<List<WeatherForecastDTO>> GetAll(DateTime startDate, System.Threading.CancellationToken cancellationToken)
2{
3    try
4    {
5        var result = await httpClient.GetFromJsonAsync<List<WeatherForecastDTO>>("/api/WeatherForecast", cancellationToken);
6        if (result != null)
7        {
8            return result;
9        }
10        return new List<WeatherForecastDTO>();
11    }
12    catch (Exception ex)
13    {
14        await Console.Out.WriteLineAsync(ex.Message);
15        throw;
16    }
17}

Controller-Methode (Übergabe des Cancellation Tokens)

1[HttpGet]
2public async Task<List<WeatherForecastDTO>> GetAll(DateTime startDate, System.Threading.CancellationToken cancellationToken)
3{
4    try
5    {
6                
7        await Task.Delay(1000, cancellationToken);
8        return Enumerable.Range(1, 5).Select(index => new WeatherForecastDTO
9        {
10            Date = startDate.AddDays(index),
11            TemperatureC = Random.Shared.Next(-20, 55),
12            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
13        }).ToList();
14    }
15    catch (Exception ex)
16    {
17        throw;
18    }
19}

Um die Funktionsweise des Cancellation Tokens besser nachvollziehen zu können, habe ich die Fehler protokolliert. Wird ein Cancellation Token abgebrochen, so wird eine TaskCanceledException ausgelöst. Auf diese kann sowohl auf der API- als auch auf der Frontend-Seite reagiert werden. Tippt man bei diesem Testprojekt auf der Weather Cancellation-Seite in das Suchfeld, sieht man in der Konsole, dass dieser Fehler protokolliert wird.

Im Vergleich zur Seite ohne Cancellation Token sieht man hier, dass bei schnellem Tippen in das Suchfeld die Daten nur einmalig aktualisiert werden und die angezeigten Daten nicht hinter dem Eingabetempo des Benutzers zurückbleiben.

No items found.
DEVWARE Team Logo
Darius S. | Softwareentwickler

Mehr zum Thema

Pfeil nach rechts (Verlinkung)
Präzise Zeitverarbeitung in .NET-Projekten mit NodaTime
03/2026

Präzise und sichere Zeitverarbeitung in .NET-Projekten

Blauer Pfeil nach rechts (Verlinkung)
C# 14 neue Sprachfeatures: Extension Members und field-Keyword in .NET 10
02/2026

C# 14 Sprachfeatures: Extension Members & field-Keyword

Blauer Pfeil nach rechts (Verlinkung)
Blazor und TypeScript gemeinsam einsetzen
02/2026

Blazor mit TypeScript: Integration & Best Practices

Blauer Pfeil nach rechts (Verlinkung)
Drag & Drop in Blazor ohne JavaScript implementieren
02/2026

Drag & Drop in Blazor ohne JavaScript: Tutorial

Blauer Pfeil nach rechts (Verlinkung)
Devware GmbH verpflichtet sich, Ihre Privatsphäre zu schützen. Wir benötigen Ihre Kontaktinformationen, um Sie bezüglich unserer Produkte und Dienstleistungen zu kontaktieren. Mit Klick auf Absenden geben Sie sich damit einverstanden. Weitere Informationen finden Sie unter Datenschutz. Ihre Daten behandeln wir vertraulich. Versprochen.
Vielen Dank für Ihr Vertrauen.
Unser Team prüft Ihre Anfrage sorgfältig und meldet sich in der Regel innerhalb von 48 Stunden bei Ihnen zurück.
Falls es besonders eilig ist, erreichen Sie uns auch telefonisch:
+ 49 (0) 202 478 269 0.
Da ist etwas schief gegangen beim Absenden des Formulars.