Abbrechen asynchroner Aufgaben nach einem bestimmten Zeitraum
Sie können einen asynchronen Vorgang nach einem gewissen Zeitraum mithilfe der CancellationTokenSource.CancelAfter-Methode abbrechen, wenn Sie nicht auf das Ende des Vorgangs warten möchten. Diese Methode plant den Abbruch aller zugeordneten Aufgaben, die innerhalb des vom CancelAfter
-Ausdruck festgelegten Zeitraums nicht abgeschlossen sind.
Dieses Beispiel fügt dem in Abbrechen einer asynchronen Aufgabe oder Aufgabenliste (C#) entwickelten Code Funktionen zum Herunterladen einer Liste von Websites und Anzeigen der Länge der Inhalte jeder Site hinzu.
In diesem Lernprogramm wird Folgendes behandelt:
- Aktualisieren einer vorhandenen .NET-Konsolenanwendung
- Planen eines Abbruchs
Voraussetzungen
Für dieses Lernprogramm ist Folgendes erforderlich:
- Erstellen einer Anwendung im Tutorial Abbrechen einer asynchronen Aufgabe oder Aufgabenliste (C#)
- .NET SDK 5 oder höher
- Integrierte Entwicklungsumgebung (Integrated Development Environment, IDE)
Aktualisieren des Einstiegspunkts der Anwendung
Ersetzen Sie die vorhandene Main
-Methode durch Folgendes:
static async Task Main()
{
Console.WriteLine("Application started.");
try
{
s_cts.CancelAfter(3500);
await SumPageSizesAsync();
}
catch (OperationCanceledException)
{
Console.WriteLine("\nTasks cancelled: timed out.\n");
}
finally
{
s_cts.Dispose();
}
Console.WriteLine("Application ending.");
}
Mit der aktualisierten Main
-Methode werden einige Anweisungsnachrichten in die Konsole geschrieben. In der try-catch
-Anweisung plant ein Aufruf von CancellationTokenSource.CancelAfter(Int32) einen Abbruch. Dadurch wird ein Abbruch nach einem bestimmten Zeitraum signalisiert.
Als Nächstes wird die SumPageSizesAsync
-Methode erwartet. Wenn die Verarbeitung aller URLs schneller erfolgt als der geplante Abbruch, wird die Anwendung beendet. Wenn jedoch der geplante Abbruch vor der Verarbeitung aller URLs ausgelöst wird, wird eine OperationCanceledException-Klasse ausgelöst.
Ausgabe der Beispielanwendung
Application started.
https://learn.microsoft.com 37,357
https://learn.microsoft.com/aspnet/core 85,589
https://learn.microsoft.com/azure 398,939
https://learn.microsoft.com/azure/devops 73,663
Tasks cancelled: timed out.
Application ending.
Vollständiges Beispiel
Der folgende Code besteht aus dem vollständigen Text der Program.cs-Datei für das Beispiel.
using System.Diagnostics;
class Program
{
static readonly CancellationTokenSource s_cts = new CancellationTokenSource();
static readonly HttpClient s_client = new HttpClient
{
MaxResponseContentBufferSize = 1_000_000
};
static readonly IEnumerable<string> s_urlList = new string[]
{
"https://learn.microsoft.com",
"https://learn.microsoft.com/aspnet/core",
"https://learn.microsoft.com/azure",
"https://learn.microsoft.com/azure/devops",
"https://learn.microsoft.com/dotnet",
"https://learn.microsoft.com/dynamics365",
"https://learn.microsoft.com/education",
"https://learn.microsoft.com/enterprise-mobility-security",
"https://learn.microsoft.com/gaming",
"https://learn.microsoft.com/graph",
"https://learn.microsoft.com/microsoft-365",
"https://learn.microsoft.com/office",
"https://learn.microsoft.com/powershell",
"https://learn.microsoft.com/sql",
"https://learn.microsoft.com/surface",
"https://learn.microsoft.com/system-center",
"https://learn.microsoft.com/visualstudio",
"https://learn.microsoft.com/windows",
"https://learn.microsoft.com/maui"
};
static async Task Main()
{
Console.WriteLine("Application started.");
try
{
s_cts.CancelAfter(3500);
await SumPageSizesAsync();
}
catch (OperationCanceledException)
{
Console.WriteLine("\nTasks cancelled: timed out.\n");
}
finally
{
s_cts.Dispose();
}
Console.WriteLine("Application ending.");
}
static async Task SumPageSizesAsync()
{
var stopwatch = Stopwatch.StartNew();
int total = 0;
foreach (string url in s_urlList)
{
int contentLength = await ProcessUrlAsync(url, s_client, s_cts.Token);
total += contentLength;
}
stopwatch.Stop();
Console.WriteLine($"\nTotal bytes returned: {total:#,#}");
Console.WriteLine($"Elapsed time: {stopwatch.Elapsed}\n");
}
static async Task<int> ProcessUrlAsync(string url, HttpClient client, CancellationToken token)
{
HttpResponseMessage response = await client.GetAsync(url, token);
byte[] content = await response.Content.ReadAsByteArrayAsync(token);
Console.WriteLine($"{url,-60} {content.Length,10:#,#}");
return content.Length;
}
}