Zaman uyumsuz görevleri belirli bir süre sonra iptal etme

İşlemin bitmesini beklemek istemiyorsanız yöntemini kullanarak CancellationTokenSource.CancelAfter zaman uyumsuz bir işlemi belirli bir süre sonra iptal edebilirsiniz. Bu yöntem, ifade tarafından belirlenen süre içinde tamamlanmamış ilişkili görevlerin iptalini CancelAfter zamanlar.

Bu örnek, web sitelerinin listesini indirmek ve her birinin içeriğinin uzunluğunu görüntülemek için Görev listesini iptal etme (C#) bölümünde geliştirilen koda eklenir.

Bu öğreticinin içindekiler:

  • Mevcut bir .NET konsol uygulamasını güncelleştirme
  • İptal zamanlaması

Ön koşullar

Bu öğretici için aşağıdakiler gereklidir:

Uygulama giriş noktasını güncelleştirme

Mevcut Main yöntemi aşağıdakilerle değiştirin:

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.");
}

Güncelleştirilmiş Main yöntem konsola birkaç yönerge iletisi yazar. try-catchiçinde, iptal zamanlamak için CancellationTokenSource.CancelAfter(Int32) bir çağrı. Bu, bir süre sonra iptal sinyali verir.

SumPageSizesAsync Ardından yöntemi beklenilir. Tüm URL'lerin işlenmesi zamanlanan iptalden daha hızlı gerçekleşirse uygulama sona erer. Ancak, tüm URL'ler işlenmeden önce zamanlanmış iptal tetiklenirse, bir OperationCanceledException oluşturulur.

Örnek uygulama çıktısı

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.

Tam örnek

Aşağıdaki kod, örnek için Program.cs dosyasının tam metnidir.

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

Ayrıca bkz.