Annuler des tâches asynch après une période spécifique
Si vous ne souhaitez pas attendre la fin d’une opération asynchrone, vous pouvez l’annuler après une période spécifique à l’aide de la méthode CancellationTokenSource.CancelAfter. Cette méthode planifie l’annulation de toutes les tâches associées qui ne sont pas terminées au terme de la période indiquée par l’expression CancelAfter
.
Cet exemple s’appuie sur le code développé dans Annuler une liste de tâches (C#) pour télécharger une liste de sites Web et afficher la longueur du contenu de chacun d’eux.
Ce didacticiel contient les sections suivantes :
- Mise à jour d’une application console .NET existante
- Planification d’une annulation
Prérequis
Ce didacticiel requiert les éléments suivants :
- Vous êtes censé avoir créé une application dans le didacticiel Annuler une liste de tâches (C#)
- Kit de développement logiciel (SDK) .NET 5 ou version ultérieure
- Environnement de développement intégré (IDE)
Mettre à jour le point d’entrée de l’application
Remplacez la méthode existante Main
par ce qui suit :
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.");
}
La méthode mise à jour Main
écrit quelques messages d’instruction dans la console. Dans l’instruction try-catch
, un appel à CancellationTokenSource.CancelAfter(Int32) planifie une annulation. Cela signale l’annulation après un certain temps.
Ensuite, la méthode SumPageSizesAsync
est attendue. Si le traitement de toutes les URL se produit plus rapidement que l’annulation planifiée, l’application se termine. Toutefois, si l’annulation planifiée est déclenchée avant que toutes les URL soient traitées, une OperationCanceledException est levée.
Exemple de sortie d’application
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.
Exemple complet
Le code suivant est le texte complet du fichier Program.cs de l’exemple.
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;
}
}