Jawaban Slaks dan Killercam baik; Saya pikir saya akan menambahkan sedikit lebih banyak konteks.
Pertanyaan pertama Anda pada dasarnya adalah tentang metode apa yang dapat ditandai async.
Metode yang ditandai sebagai asyncdapat kembali void, Taskatau Task<T>. Apa perbedaan di antara mereka?
Sebuah Task<T>metode async kembali dapat ditunggu, dan ketika tugas selesai akan mengajukan up T. sebuah
Sebuah Taskmetode async kembali dapat ditunggu, dan ketika selesai tugas, kelanjutan dari tugas dijadwalkan untuk berjalan.
SEBUAH void metode async kembali tidak dapat ditunggu; itu adalah metode "tembak dan lupakan". Itu bekerja secara tidak sinkron, dan Anda tidak memiliki cara untuk mengetahui kapan itu dilakukan. Ini lebih dari sedikit aneh; seperti kata SLaks, biasanya Anda hanya akan melakukan itu ketika membuat pengendali event asinkron. Acara menyala, pawang mengeksekusi; tidak ada yang akan "menunggu" tugas dikembalikan oleh pengendali acara karena penangan acara tidak mengembalikan tugas, dan bahkan jika mereka melakukannya, kode apa yang akan menggunakan Tugas untuk sesuatu? Biasanya bukan kode pengguna yang mentransfer kontrol ke handler sejak awal.
Pertanyaan kedua Anda, dalam komentar, pada dasarnya adalah tentang apa yang bisa awaitdiedit:
Metode apa yang bisa awaitdiedit? Apakah metode pengembalian yang dibatalkan dapat awaitdiedit?
Tidak, metode pengembalian batal tidak bisa ditunggu. Kompiler diterjemahkan await M()menjadi panggilan ke M().GetAwaiter(), di mana GetAwaitermungkin metode instance atau metode ekstensi. Nilai yang ditunggu harus berupa nilai yang bisa Anda dapatkan sebagai penunggu; jelas metode pengembalian-kembali tidak menghasilkan nilai dari mana Anda bisa mendapatkan penunggu.
Task-Mengembalikan metode dapat menghasilkan nilai yang bisa ditunggu. Kami mengantisipasi bahwa pihak ketiga akan ingin membuat implementasi sendiri Taskobjek-seperti yang dapat ditunggu, dan Anda akan dapat menunggu mereka. Namun, Anda tidak akan diizinkan untuk mendeklarasikan asyncmetode yang mengembalikan apa pun kecuali void, Taskatau Task<T>.
(PEMBARUAN: Kalimat terakhir saya mungkin dipalsukan oleh versi C # yang akan datang; ada proposal untuk memperbolehkan tipe yang dikembalikan selain tipe tugas untuk metode async.)
(PEMBARUAN: Fitur yang disebutkan di atas berhasil masuk ke C # 7.)