Di C #, ketika Anda mengganti metode, itu diizinkan untuk membuat menimpa async ketika metode asli tidak. Ini sepertinya bentuk yang buruk.
Contoh yang membawa saya ke sini adalah ini - saya dibawa untuk membantu dengan masalah uji beban. Pada sekitar 500 pengguna secara bersamaan, proses login akan mogok dalam redirect loop. IIS sedang mencatat pengecualian dengan pesan "Modul atau pengendali asinkron selesai sementara operasi asinkron masih tertunda". Beberapa pencarian membuat saya berpikir bahwa seseorang sedang melecehkan async void
, tetapi pencarian cepat saya melalui sumber tidak dapat menemukan apa pun.
Sayangnya, saya sedang mencari 'async \ svoid' (pencarian regex) ketika saya seharusnya mencari sesuatu yang lebih seperti 'async \ s [^ T]' (dengan asumsi Task tidak sepenuhnya memenuhi syarat ... Anda mengerti maksudnya).
Apa yang kemudian saya temukan adalah async override void onActionExecuting(...
di basis controller. Jelas itu yang menjadi masalah, dan memang begitu. Memperbaiki itu (membuatnya sinkron untuk saat ini) menyelesaikan masalah.
Kembali ke pertanyaan: Mengapa oh mengapa Anda dapat menandai override sebagai async ketika kode panggilan tidak pernah bisa menunggu?
Task
.Jawaban:
Kata kunci async memungkinkan metode untuk menggunakan
await
sintaksis dalam definisinya. Saya bisaawait
pada metode apa pun yang mengembalikanTask
tipe terlepas dari apakah itu metode async.void
adalah tipe pengembalian yang legal (walaupun tidak disarankan ) untuk metode async, jadi mengapa itu tidak diizinkan? Dari luar,async
tidak memungkinkan apa pun yang tidak dapat Anda lakukan tanpanya. Metode yang Anda mengalami masalah bisa saja ditulis untuk berperilaku sama persis tanpa async. Definisi itu hanya akan lebih bertele-tele.Untuk penelepon, sebuah
async T
metode adalah metode normal yang kembaliT
(yang terbatasvoid
,Task
atauTask<A>
). Itu adalah metode async bukan bagian dari antarmuka. Perhatikan bahwa kode berikut ini ilegal:Itu (atau kode serupa di kelas abstrak) menghasilkan pesan kesalahan berikut di VS2012:
Jika saya memang bermaksud metode dalam antarmuka atau kelas induk biasanya asinkron, saya tidak bisa menggunakannya
async
untuk berkomunikasi itu. Jika saya ingin mengimplementasikannya denganawait
sintaks, saya harus dapat memiliki metode override async (dalam kasus kelas induk).sumber
override
sama sekali, tapi itulah pertanyaannya.async
tidak mengubah antarmuka metode, hanya apa yang secara sintaksis diizinkan dalam definisi, jadi apakah itu menimpa atau tidak sama sekali tidak relevan.async
pengubah hanya dapat diterapkan pada implementasi. Anda tidak dapat mendeklarasikan metode async dalam suatu antarmuka, misalnya, menggarisbawahi bahwa apakah suatu metode async atau tidak bukan bagian dari antarmuka.Satu-satunya tujuan kata kunci async adalah untuk menunggu di dalam tubuh dari fungsi kata kunci tersebut. Ini diperlukan agar menambahkan fungsi menunggu tidak merusak kode yang ada. Microsoft memutuskan untuk menggunakan menunggu opsi opt-in. Untuk fungsi yang tidak ditandai async, Anda dapat menentukan variabel bernama menunggu tanpa masalah.
Oleh karena itu async bukan bagian dari tanda tangan fungsi dan tidak memiliki makna semantik dalam kode IL yang dihasilkan. Itu ada di sana untuk kompiler untuk mengetahui cara mengkompilasi fungsi dengan benar. Itu juga menginstruksikan kompiler untuk memastikan bahwa hanya Tugas, Tugas <T> atau batal yang dikembalikan.
sumber