Dela via


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:

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-catchI , 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;
    }
}

Se även