Learning SynchronizationContext, async, dan await

Pemrograman asinkron adalah bentuk pemrograman paralel yang memungkinkan Anda menjalankan tugas secara terpisah dari thread aplikasi utama dan kemudian memberi tahu thread saat eksekusi selesai. Asynchrony membantu Anda menjalankan tugas tanpa perlu menahan aliran eksekusi atau daya tanggap aplikasi Anda.

Microsoft telah menyediakan dukungan untuk pemrograman paralel di .Net Framework untuk memanfaatkan keunggulan sistem multi inti. Anda dapat memanfaatkan asinkron untuk meningkatkan kinerja dan daya tanggap aplikasi Anda.

Pada dasarnya, ada dua jenis operasi yang mungkin dalam sebuah aplikasi. Ini termasuk operasi terikat komputasi dan I / O. Operasi terikat komputasi adalah operasi di mana komputasi dapat dilakukan pada thread terpisah sehingga thread utama dapat melanjutkan eksekusinya. Sebaliknya, operasi terikat I / O adalah operasi yang dijalankan secara eksternal dan karenanya tidak perlu memblokir utas saat ini saat I / O sedang berlangsung.

Konteks sinkronisasi dan konteks eksekusi

Setiap utas memiliki konteks yang terkait dengannya - ini juga dikenal sebagai konteks "saat ini" - dan konteks ini dapat dibagikan di seluruh utas. ExecutionContext berisi metadata yang relevan dari lingkungan atau konteks saat ini di mana program sedang dijalankan. SynchronizationContext mewakili abstraksi - ini menunjukkan lokasi tempat kode aplikasi Anda dijalankan.

SynchronizationContext memungkinkan Anda mengantrekan tugas ke konteks lain. Perhatikan bahwa setiap utas dapat memiliki SynchronizatonContext-nya sendiri. Kelas SynchronizationContext telah ditambahkan baru-baru ini ke namespace System.Threading dan memfasilitasi komunikasi antar utas. Anda dapat membaca lebih lanjut tentang SynchronizationContext dan ExecutionContext di sini.

Menyelam lebih dalam di Async dan Await

Tiga pola pemrograman asynchronous meliputi:

  1. Model Pemrograman Asinkron (APM)
  2. Pola Asinkron Berbasis Peristiwa (EAP)
  3. Pola Asinkron Berbasis Tugas (TAP)

Terbaru, paling direkomendasikan dan paling elegan dari semua ini adalah TAP.

Perhatikan bahwa Anda dapat menandai metode menggunakan kata kunci "async" yang mengembalikan void, Task, atau Task. Perhatikan bahwa ketika pengecualian terjadi di dalam metode asynchronous yang memiliki tipe kembalian dari Tugas atau Tugas, detail pengecualian disimpan di dalam contoh Tugas.

Sebaliknya, jika pengecualian terjadi di dalam metode asinkron yang memiliki tipe kembalian kekosongan, detail pengecualian disimpan di dalam SynchronizationContext yang aktif pada saat metode asinkron dipanggil. Intinya, Anda tidak dapat menangani pengecualian yang dimunculkan dalam metode asinkron yang memiliki tipe kembalian void menggunakan penangan pengecualian yang ditulis di dalam metode asinkron. Karena komputasi dan semantik penanganan error yang berbeda, disarankan untuk menghindari metode asinkron yang memiliki tipe kembalian void kecuali jika ada alasan yang memadai untuk menggunakannya.

Ketika Anda menggunakan kata kunci "await" di dalam metode asynchronous, metode tersebut dibagi di dalam mesin negara. Perhatikan bahwa kata kunci "await" menangkap SynchronizationContext saat ini dan segera setelah tugas yang telah ditunggu menggunakan kata kunci "await" selesai, mesin status dilanjutkan dan eksekusi kode dalam metode pemanggil dimulai ulang - ini juga dikenal sebagai kelanjutan. Jika eksekusi kode yang telah ditunggu menggunakan kata kunci "await" telah diselesaikan pada saat titik suspensi ditemukan, metode asinkron (metode yang telah ditandai sebagai "async") akan dijalankan secara sinkron. Apabila eksekusi kode yang ditunggu belum selesai, maka kelanjutan delegasi dilampirkan pada kode yang telah ditunggu tersebut.

Anda dapat memanfaatkan metode asinkron yang mengembalikan void untuk membuat penangan kejadian asinkron. Metode Utama tidak dapat ditandai dengan kata kunci "async" karena ini adalah titik masuk aplikasi - metode Utama "asinkron" akan berhenti saat dipanggil. Kata kunci "await" memberi tahu kompiler bahwa metode tersebut dapat memiliki titik penangguhan dan dimulainya kembali. Kebetulan, Anda dapat menggunakan kata kunci "await" hanya pada metode yang telah ditandai sebagai asinkron menggunakan kata kunci "async".

Metode asinkron saat dipanggil, berjalan secara sinkron pada thread saat ini, apa pun jenis kembalian metode tersebut. Saat Anda menandai suatu metode sebagai asynchronous menggunakan kata kunci "async", Anda cukup memberi tahu compiler bahwa metode tersebut dapat dibagi menjadi beberapa tugas - beberapa tugas ini dapat dijalankan secara asynchronous. Selain itu, penyertaan kata kunci "async" dalam sebuah metode tidak mengantrekan pemanggilan metode sebagai bagian dari kumpulan thread. Asynchrony (yaitu, apakah suatu metode akan memiliki perilaku asinkron) sebenarnya bergantung pada titik penangguhan yang telah Anda sebutkan dalam metode Anda menggunakan kata kunci "await". Jika Anda tidak menyertakan kata kunci "await" di dalam metode asinkron, seluruh metode akan dijalankan secara sinkron.