Pemanggil method asinkron membutuhkan sesuatu yang mewakili pekerjaan yang sedang berlangsung, karena hasilnya belum tersedia saat pemanggilan dilakukan. Tipe Task adalah tipe pustaka .NET yang memenuhi kebutuhan itu: sebuah objek yang menandai pekerjaan yang sedang berjalan, yang statusnya dapat kita periksa dan hasilnya dapat kita tunggu dengan await. Task dipakai untuk pekerjaan tanpa nilai kembali, sedangkan Task<T> dipakai ketika pekerjaan menghasilkan satu nilai bertipe T.

Status dan Siklus Task #

Setiap objek Task membawa properti Status yang bergerak melalui beberapa nilai:

  • Created: task baru dibuat dan belum mulai dieksekusi.
  • WaitingForActivation: task sedang menunggu bagian pekerjaan yang belum selesai, misalnya timer Task.Delay.
  • RanToCompletion: pekerjaan selesai tanpa galat.
  • Faulted dan Canceled: pekerjaan berakhir karena exception atau pembatalan, yang dibahas pada bab Exception dalam Async dan bab Cancellation Token.

Pemanggilan method asinkron berjalan secara sinkron sampai await pertama. Setelah titik itu, method mengembalikan objek Task kepada pemanggil sementara sisanya menunggu.

Contoh: Task Tanpa Hasil dan Task dengan Hasil #

Kode berikut memulai satu Task untuk mencetak promo dan satu Task<int> untuk menghitung total belanja:

csharp
static async Task TampilkanPromoAsync()
{
    await Task.Delay(50);
    Console.WriteLine("Promo hari ini: gratis ongkir");
}

static async Task<int> HitungTotalAsync(int jumlah, int hargaSatuan)
{
    await Task.Delay(100);
    return jumlah * hargaSatuan;
}

// Pemanggil:
Task tanpaHasil = TampilkanPromoAsync();
Task<int> hitung = HitungTotalAsync(3, 15000);

Console.WriteLine($"Status awal hitung: {hitung.Status}");

await tanpaHasil;
int total = await hitung;
Console.WriteLine($"Total belanja: Rp{total}");
Console.WriteLine($"Status akhir hitung: {hitung.Status}");

Output yang Dihasilkan:

text
Status awal hitung: WaitingForActivation
Promo hari ini: gratis ongkir
Total belanja: Rp45000
Status akhir hitung: RanToCompletion

Mari kita telaah baris-baris pentingnya:

  1. Task tanpaHasil = TampilkanPromoAsync(): pemanggilan mengembalikan objek Task tanpa nilai; method cukup async Task karena tidak mengembalikan apa pun.
  2. Task<int> hitung = HitungTotalAsync(3, 15000): objek Task<int> menjanjikan satu nilai int yang belum tersedia.
  3. hitung.Status: status terbaca WaitingForActivation karena method sudah berhenti di await Task.Delay dan pekerjaan itu belum usai.
  4. int total = await hitung: await mengeluarkan nilai dari Task<int>; hasil await adalah int, bukan Task<int> lagi.
  5. hitung.Status pada akhir: status berubah menjadi RanToCompletion setelah nilai dikembalikan.

Bab berikutnya membongkar mekanisme kata kunci async dan await yang menjadi fondasi seluruh pola ini.