Akhir-akhir ini saya sepertinya tidak bisa mendapatkan cukup dari pola async-wait yang menakjubkan dari C # 5.0. Di mana saja kau selama hidup saya?
Saya benar-benar senang dengan sintaks yang sederhana, tetapi saya mengalami satu kesulitan kecil. Masalah saya adalah bahwa fungsi-fungsi async memiliki deklarasi yang sama sekali berbeda dari fungsi-fungsi biasa. Karena hanya fungsi-fungsi async yang dapat menunggu pada fungsi-fungsi async lainnya, ketika saya mencoba untuk mem-porting beberapa kode pemblokiran lama ke async, saya mempunyai efek domino dari fungsi-fungsi yang harus saya konversi.
Orang-orang menyebut ini sebagai serangan zombie . Saat async menggigit kode Anda, kode itu akan terus bertambah besar. Proses porting tidak sulit, hanya membuang async
deklarasi dan membungkus nilai pengembaliannya Task<>
. Tapi itu menjengkelkan untuk melakukan ini berulang-ulang ketika porting kode sinkron lama.
Sepertinya saya akan jauh lebih alami jika kedua tipe fungsi (async dan sinkronisasi lama polos) memiliki sintaks yang sama persis. Jika ini masalahnya, porting akan mengambil upaya nol dan saya bisa beralih tanpa rasa sakit di antara dua bentuk.
Saya pikir ini bisa berhasil jika kita mengikuti aturan ini:
Fungsi-fungsi Async tidak membutuhkan
async
deklarasi lagi. Jenis kembali mereka tidak harus dibungkusTask<>
. Compiler akan mengidentifikasi fungsi async selama kompilasi dengan sendirinya dan melakukan pembungkus Tugas <> secara otomatis sesuai kebutuhan.Tidak ada lagi panggilan api dan lupa fungsi async. Jika Anda ingin memanggil fungsi async, Anda harus menunggu di sana. Saya jarang menggunakan api-dan-lupa, dan semua contoh kondisi balapan gila atau kebuntuan selalu tampaknya didasarkan pada mereka. Saya pikir mereka terlalu membingungkan dan "tidak terhubung" dengan pola pikir yang sinkron yang kami coba utarakan.
Jika Anda benar-benar tidak dapat hidup tanpa api-dan-lupa, akan ada sintaks khusus untuk itu. Bagaimanapun, itu tidak akan menjadi bagian dari sintaksis terpadu sederhana yang saya bicarakan.
Satu-satunya kata kunci yang Anda perlukan untuk menunjukkan panggilan asinkron adalah
await
. Jika Anda menunggu, panggilan tidak sinkron. Jika tidak, panggilannya adalah sinkron lama (ingat, kami tidak punya api dan lupakan lagi).Compiler akan mengidentifikasi fungsi-fungsi async secara otomatis (karena mereka tidak memiliki deklarasi khusus lagi). Aturan 4 membuat ini sangat mudah dilakukan - jika suatu fungsi memiliki
await
panggilan di dalamnya, itu async.
Bisakah ini bekerja? atau aku melewatkan sesuatu? Sintaksis terpadu ini jauh lebih lancar dan bisa menyelesaikan infestasi zombie sama sekali.
Beberapa contoh:
// assume this is an async function (has await calls inside)
int CalcRemoteBalanceAsync() { ... }
// assume this is a regular sync function (has no await calls inside)
int CalcRemoteBalance() { ... }
// now let's try all combinations and see what they do:
// this is the common synchronous case - it will block
int b1 = CalcRemoteBalance();
// this is the common asynchronous case - it will not block
int b2 = await CalcRemoteBalanceAsync();
// choosing to call an asynchronous function in a synchronous manner - it will block
// this syntax was used previously for async fire-and-forget, but now it's just synchronous
int b3 = CalcRemoteBalanceAsync();
// strange combination - it will block since it's calling a synchronous function
// it should probably show a compilation warning though
int b4 = await CalcRemoteBalance();
Catatan: ini merupakan kelanjutan dari diskusi terkait yang menarik di SO
await
segera melakukannya. Anda dapat melakukan sesuatu seperti var task = FooAsync(); Bar(); await task;
. Bagaimana saya melakukan ini dalam proposal Anda?
async
. Saya pikir itu salah satu keuntungan besar dari async
- await
: bahwa ini memungkinkan Anda untuk dengan mudah menyusun operasi asinkron (dan tidak hanya dengan cara "mulai A, tunggu A, mulai B, tunggu B" yang paling sederhana). Dan sudah ada sintaks khusus persis untuk tujuan ini: itu disebut await
.