Bagikan melalui


Membatalkan tugas asinkron setelah jangka waktu tertentu

Anda dapat membatalkan operasi asinkron setelah periode waktu tertentu dengan menggunakan metode CancellationTokenSource.CancelAfter, jika Anda tidak ingin menunggu operasi selesai. Metode ini menjadwalkan pembatalan tugas terkait yang tidak selesai dalam jangka waktu yang ditentukan oleh ekspresi CancelAfter.

Contoh ini menambahkan ke kode yang dikembangkan di Batalkan daftar tugas (C#) untuk mengunduh daftar situs web dan untuk menampilkan panjang konten masing-masing.

Tutorial ini mencakup:

  • Memperbarui aplikasi konsol .NET yang ada
  • Menjadwalkan pembatalan

Prasyarat

Tutorial ini memerlukan hal-hal berikut:

Memperbarui entry point aplikasi

Ganti metode Main yang sudah ada dengan kode berikut:

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

Metode Main yang diperbarui menulis beberapa pesan instruksi ke konsol. try-catchDalam , panggilan untuk menjadwalkan CancellationTokenSource.CancelAfter(Int32) pembatalan. Ini akan memberi sinyal pembatalan setelah jangka waktu tertentu.

Selanjutnya, metode SumPageSizesAsync akan ditunggu. Jika pemrosesan semua URL terjadi lebih cepat daripada pembatalan terjadwal, maka aplikasi akan berakhir. Namun, jika pembatalan terjadwal dipicu sebelum semua URL diproses, OperationCanceledException akan dilemparkan.

Contoh output aplikasi

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.

Contoh lengkap

Kode berikut adalah teks lengkap dari file Program.cs sebagai contoh.

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

Lihat juga