Asynchrone taken na een bepaalde periode annuleren
U kunt een asynchrone bewerking na een bepaalde periode annuleren met behulp van de CancellationTokenSource.CancelAfter methode als u niet wilt wachten totdat de bewerking is voltooid. Met deze methode wordt de annulering van de bijbehorende taken gepland die niet binnen de periode zijn voltooid die door de CancelAfter
expressie is aangewezen.
In dit voorbeeld wordt de code toegevoegd die is ontwikkeld in Een lijst met taken annuleren (C#) om een lijst met websites te downloaden en de lengte van de inhoud van elke site weer te geven.
In deze zelfstudie komt het volgende aan bod:
- Een bestaande .NET-consoletoepassing bijwerken
- Een annulering plannen
Vereisten
Voor deze zelfstudie hebt u het volgende nodig:
- U hebt naar verwachting een toepassing gemaakt in de zelfstudie Een lijst met taken annuleren (C#)
- SDK voor .NET 5 of hoger
- Integrated Development Environment (IDE)
Toepassingsinvoerpunt bijwerken
Vervang de bestaande Main
methode door het volgende:
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.");
}
Met de bijgewerkte Main
methode worden enkele instructieberichten naar de console geschreven. Binnen de try-catch
, een oproep om CancellationTokenSource.CancelAfter(Int32) een annulering te plannen. Dit zal na een bepaalde periode op annulering wijzen.
Vervolgens wordt de SumPageSizesAsync
methode verwacht. Als alle URL's sneller worden verwerkt dan de geplande annulering, eindigt de toepassing. Als de geplande annulering echter wordt geactiveerd voordat alle URL's worden verwerkt, wordt er een OperationCanceledException gegenereerd.
Voorbeeld van toepassingsuitvoer
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.
Volledig voorbeeld
De volgende code is de volledige tekst van het bestand Program.cs voor het voorbeeld.
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;
}
}