Avbryta asynkrona aktiviteter efter en tidsperiod
Du kan avbryta en asynkron åtgärd efter en viss tidsperiod med hjälp CancellationTokenSource.CancelAfter av metoden om du inte vill vänta tills åtgärden har slutförts. Den här metoden schemalägger annulleringen av associerade aktiviteter som inte har slutförts inom den tidsperiod som anges av CancelAfter
uttrycket.
Det här exemplet lägger till i koden som har utvecklats i Avbryt en lista med uppgifter (C#) för att ladda ned en lista över webbplatser och för att visa längden på innehållet i var och en av dem.
Den här självstudiekursen omfattar:
- Uppdatera ett befintligt .NET-konsolprogram
- Schemalägga en annullering
Förutsättningar
För den här kursen behöver du följande:
- Du förväntas ha skapat ett program i självstudien Avbryt en lista med uppgifter (C#)
- .NET 5 eller senare SDK
- Integrerad utvecklingsmiljö (IDE)
Uppdatera programmets startpunkt
Ersätt den befintliga Main
metoden med följande:
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.");
}
Den uppdaterade Main
metoden skriver några instruktionsmeddelanden till konsolen. try-catch
I , ett anrop till CancellationTokenSource.CancelAfter(Int32) schemalägger en annullering. Detta kommer att signalera annullering efter en tidsperiod.
SumPageSizesAsync
Därefter väntar metoden. Om bearbetningen av alla URL:er sker snabbare än den schemalagda annulleringen avslutas programmet. Men om den schemalagda annulleringen utlöses innan alla URL:er bearbetas genereras en OperationCanceledException .
Exempel på programutdata
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.
Fullständigt exempel
Följande kod är den fullständiga texten i Filen Program.cs för exemplet.
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;
}
}