Pengguna menutup halaman unduhan, koneksi terputus, atau permintaan HTTP kedaluwarsa; operasi asinkron yang sedang berjalan perlu dihentikan dengan rapi. .NET menyelesaikan kebutuhan ini lewat model pembatalan kooperatif: objek CancellationTokenSource memegang kendali atas sinyal pembatalan, sementara CancellationToken diteruskan ke method yang berjalan dan diperiksa oleh kode itu sendiri. Runtime tidak memaksa sebuah method berhenti; method yang bersangkutan yang memutuskan kapan ia berhenti.

Komponen Pembatalan Kooperatif #

  • CancellationTokenSource: sumber sinyal; pemegangnya memanggil Cancel() atau menjadwalkan CancelAfter().
  • CancellationToken: tiket yang diteruskan ke method kerja; membawa status permintaan pembatalan.
  • ThrowIfCancellationRequested(): pemeriksaan eksplisit di titik aman; melempar OperationCanceledException bila sinyal sudah menyala.
  • Task.Delay(ms, token): menunggu yang responsif; penundaan langsung berakhir dengan exception begitu sinyal menyala.

Karena pemeriksaan dilakukan oleh kode kerja, penempatan titik pemeriksaan menentukan seberapa cepat operasi merespons pembatalan.

Contoh: Membatalkan Unduhan Bertahap #

Kode berikut mengunduh laporan lima bagian, lalu membatalkannya di tengah jalan melalui CancelAfter:

csharp
static async Task UnduhLaporanAsync(string nama, CancellationToken token)
{
    for (int bagian = 1; bagian <= 5; bagian++)
    {
        token.ThrowIfCancellationRequested();
        await Task.Delay(100, token);
        Console.WriteLine($"Bagian {bagian} selesai diunduh");
    }
    Console.WriteLine($"Unduhan {nama} lengkap");
}

// Pemanggil:
using CancellationTokenSource cts = new();

Task unduhan = UnduhLaporanAsync("laporan-2024.csv", cts.Token);
cts.CancelAfter(250);

try
{
    await unduhan;
    Console.WriteLine("Unduhan selesai penuh");
}
catch (OperationCanceledException)
{
    Console.WriteLine($"Unduhan dihentikan. Status task: {unduhan.Status}");
}

Output yang Dihasilkan:

text
Bagian 1 selesai diunduh
Bagian 2 selesai diunduh
Unduhan dihentikan. Status task: Canceled

Mari kita bedah alurnya:

  1. using CancellationTokenSource cts = new(): sumber sinyal dibuat dan dibuang otomatis setelah blok berakhir.
  2. cts.CancelAfter(250): sinyal dijadwalkan menyala 250 ms kemudian, di tengah penundaan bagian ketiga.
  3. token.ThrowIfCancellationRequested(): setiap putaran memeriksa sinyal di awal; bagian 1 dan 2 lolos karena sinyal belum menyala.
  4. await Task.Delay(100, token): penundaan bagian 3 terputus ketika sinyal menyala; exception TaskCanceledException yang merupakan turunan OperationCanceledException terlempar.
  5. catch (OperationCanceledException): pemanggil menangkapnya dan membaca status Canceled dari task.

Selain berhenti karena dibatalkan, operasi asinkron bisa berakhir karena kesalahan. Bab berikutnya membahas penanganan exception dalam kode asinkron.