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:

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

Zie ook