Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Jika Anda menulis kelas dengan beberapa operasi yang mungkin menimbulkan penundaan yang nyata, pertimbangkan untuk memberikannya fungsionalitas asinkron dengan menerapkan Pola Asinkron berbasis Peristiwa.
Pola Asinkron berbasis Peristiwa menyediakan cara standar untuk mengemas kelas yang memiliki fitur asinkron. Jika diimplementasikan dengan kelas pembantu seperti AsyncOperationManager, kelas Anda akan berfungsi dengan benar di bawah model aplikasi apa pun, termasuk aplikasi ASP.NET, Konsol, dan Formulir Windows.
Untuk contoh yang mengimplementasikan Pola Asinkron berbasis Peristiwa, lihat Cara: Menerapkan Komponen yang Mendukung Pola Asinkron berbasis Peristiwa.
Untuk operasi asinkron sederhana, Anda mungkin menemukan komponen yang BackgroundWorker cocok. Untuk informasi selengkapnya tentang BackgroundWorker, lihat Cara: Menjalankan Operasi di Latar Belakang.
Daftar berikut menjelaskan fitur Pola Asinkron berbasis Peristiwa yang dibahas dalam topik ini.
Peluang untuk Menerapkan Pola Asinkron Berbasis Peristiwa
Penamaan Metode Asinkron
Mendukung Pembatalan secara Opsional
Secara opsional Mendukung Properti IsBusy
Secara opsional Berikan Dukungan untuk Pelaporan Kemajuan
Secara opsional Berikan Dukungan untuk Mengembalikan Hasil Bertahap
Menangani Parameter Out dan Ref dalam Metode
Peluang untuk Menerapkan Pola Asinkron Berbasis Peristiwa
Pertimbangkan untuk menerapkan Pola Asinkron berbasis Peristiwa saat:
Klien dari kelas Anda tidak memerlukan objek WaitHandle dan IAsyncResult untuk operasi asinkron, yang berarti polling dan WaitAll atau WaitAny perlu dibangun oleh klien.
Anda ingin agar operasi asinkron dikelola klien menggunakan model acara/delegasi yang sudah dikenal.
Setiap operasi adalah kandidat untuk implementasi asinkron, tetapi mereka yang Anda harapkan akan menimbulkan latensi panjang harus dipertimbangkan. Operasi yang paling tepat adalah di mana klien memanggil metode dan diberi tahu tentang penyelesaian, tanpa perlu intervensi lebih lanjut. Juga sesuai adalah operasi yang berjalan terus menerus, secara berkala memberi tahu klien tentang kemajuan, hasil inkremental, atau perubahan status.
Untuk informasi selengkapnya tentang memutuskan kapan harus mendukung Pola Asinkron Berbasis Peristiwa, lihat Memutuskan Kapan Harus Menerapkan Pola Asinkron berbasis Peristiwa.
Penamaan Metode Asinkron
Untuk setiap metode sinkron MethodName yang ingin Anda berikan mitra asinkron:
Tentukan metode MethodNameAsync yang:
Menampilkan
void.Mengambil parameter yang sama dengan metode MethodName .
Menerima beberapa pemanggilan.
Secara opsional tentukan suatu overload MethodNameAsync yang identik dengan MethodNameAsync, tetapi dengan parameter tambahan yang bernilai objek dan disebut userState. Lakukan ini jika Anda siap untuk mengelola beberapa pemanggilan bersamaan metode Anda, dalam hal ini nilai userState akan dikirimkan kembali ke semua penangan kejadian untuk membedakan pemanggilan metode. Anda juga dapat memilih untuk melakukan ini hanya sebagai tempat untuk menyimpan status pengguna untuk pengambilan nanti.
Untuk setiap tanda tangan metode MethodNameAsync terpisah:
Tentukan peristiwa berikut di kelas yang sama dengan metode :
Public Event MethodNameCompleted As MethodNameCompletedEventHandlerpublic event MethodNameCompletedEventHandler MethodNameCompleted;Tentukan delegasi berikut dan AsyncCompletedEventArgs. Ini kemungkinan akan didefinisikan di luar kelas itu sendiri, tetapi di namespace yang sama.
Public Delegate Sub MethodNameCompletedEventHandler( _ ByVal sender As Object, _ ByVal e As MethodNameCompletedEventArgs) Public Class MethodNameCompletedEventArgs Inherits System.ComponentModel.AsyncCompletedEventArgs Public ReadOnly Property Result() As MyReturnType End Propertypublic delegate void MethodNameCompletedEventHandler(object sender, MethodNameCompletedEventArgs e); public class MethodNameCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { public MyReturnType Result { get; } }Pastikan bahwa kelas MethodNameCompletedEventArgs mengekspos anggotanya sebagai properti baca-saja, dan bukan bidang, karena bidang mencegah pengikatan data.
Jangan tentukan kelas turunan apa pun AsyncCompletedEventArgsuntuk metode yang tidak menghasilkan hasil. Cukup gunakan sendiri instans AsyncCompletedEventArgs itu.
Nota
Ini sepenuhnya dapat diterima, ketika layak dan sesuai, untuk menggunakan kembali delegasi dan AsyncCompletedEventArgs tipe. Dalam hal ini, penamaan tidak akan sepenuhnya konsisten dengan nama metode, karena baik delegasi tertentu maupun AsyncCompletedEventArgs tidak terikat pada satu metode saja.
Mendukung Pembatalan secara Opsional
Jika kelas Anda akan mendukung pembatalan operasi asinkron, pembatalan harus diekspos ke klien seperti yang dijelaskan di bawah ini. Ada dua poin keputusan yang perlu dicapai sebelum menentukan dukungan pembatalan Anda:
- Apakah kelas Anda, termasuk penambahan yang diantisipasi di masa mendatang, hanya memiliki satu operasi asinkron yang mendukung pembatalan?
- Dapatkah operasi asinkron yang mendukung pembatalan mendukung beberapa operasi yang tertunda? Artinya, apakah metode MethodNameAsync mengambil sebuah
userStateparameter, dan apakah memungkinkan beberapa pemanggilan sebelum menunggu salah satu selesai?
Gunakan jawaban atas dua pertanyaan ini dalam tabel di bawah ini untuk menentukan apa tanda tangan untuk metode pembatalan Anda.
Visual Basic
| Beberapa Operasi Simultan Didukung | Hanya Satu Operasi pada Satu Waktu | |
|---|---|---|
| Satu Operasi Asinkron di seluruh kelas | Sub MethodNameAsyncCancel(ByVal userState As Object) |
Sub MethodNameAsyncCancel() |
| Beberapa Operasi Asinkron di kelas | Sub CancelAsync(ByVal userState As Object) |
Sub CancelAsync() |
C#
| Beberapa Operasi Simultan Didukung | Hanya Satu Operasi pada Satu Waktu | |
|---|---|---|
| Satu Operasi Asinkron di seluruh kelas | void MethodNameAsyncCancel(object userState); |
void MethodNameAsyncCancel(); |
| Beberapa Operasi Asinkron di kelas | void CancelAsync(object userState); |
void CancelAsync(); |
Jika Anda menentukan metode CancelAsync(object userState), klien harus berhati-hati ketika memilih nilai status mereka supaya mampu membedakan di antara semua metode asinkron yang dipanggil pada objek, dan bukan hanya semua pemanggilan metode asinkron tunggal.
Keputusan untuk memberi nama versi operasi asinkron tunggal MethodNameAsyncCancel didasarkan pada mampu menemukan metode dengan lebih mudah di lingkungan desain seperti IntelliSense Visual Studio. Ini mengelompokkan anggota terkait dan membedakannya dari anggota lain yang tidak ada hubungannya dengan fungsionalitas asinkron. Jika Anda mengharapkan bahwa mungkin ada operasi asinkron tambahan yang ditambahkan dalam versi berikutnya, lebih baik untuk menentukan CancelAsync.
Jangan tentukan beberapa metode dari tabel di atas di kelas yang sama. Itu tidak akan masuk akal, atau akan mengacaukan antarmuka kelas dengan proliferasi metode.
Metode ini biasanya akan segera kembali, dan operasi mungkin atau mungkin tidak benar-benar membatalkan. Dalam penanganan aktivitas untuk peristiwa MethodNameCompleted , objek MethodNameCompletedEventArgs berisi Cancelled bidang, yang dapat digunakan klien untuk menentukan apakah pembatalan terjadi.
Mematuhi semantik pembatalan yang dijelaskan dalam Praktik Terbaik untuk Menerapkan Pola Asinkron berbasis Peristiwa.
Secara opsional Mendukung Properti IsBusy
Jika kelas Anda tidak mendukung beberapa pemanggilan bersamaan, pertimbangkan untuk mengekspos properti IsBusy. Ini memungkinkan pengembang untuk menentukan apakah metode MethodNameAsync berjalan tanpa menangkap pengecualian dari metode MethodNameAsync .
Mematuhi semantik yang IsBusy dijelaskan dalam Praktik Terbaik untuk Menerapkan Pola Asinkron berbasis Peristiwa.
Secara opsional Berikan Dukungan untuk Pelaporan Kemajuan
Kadang-kadang penting bagi operasi asinkron untuk melaporkan kemajuan selama operasinya. Pola Asinkron berbasis Peristiwa menyediakan pedoman untuk melakukannya.
Secara opsional, tentukan peristiwa yang akan dipicu oleh operasi asinkron dan dijalankan pada utas yang sesuai. Objek ProgressChangedEventArgs membawa indikator kemajuan bernilai bilangan bulat yang diharapkan antara 0 dan 100.
Beri nama kejadian ini sebagai berikut:
ProgressChangedjika kelas memiliki beberapa operasi asinkron (atau diharapkan tumbuh untuk menyertakan beberapa operasi asinkron dalam versi mendatang);MethodNameProgressChanged jika kelas memiliki satu operasi asinkron.
Pilihan penamaan ini paralel dengan pilihan yang dibuat untuk metode pembatalan yang disebutkan, seperti yang dijelaskan di bagian Mendukung Pembatalan Secara Opsional.
Acara ini harus menggunakan tanda tangan delegate ProgressChangedEventHandler dan kelas ProgressChangedEventArgs. Atau, jika indikator kemajuan yang lebih spesifik untuk domain dapat disediakan (misalnya, byte yang telah dibaca dan total byte untuk operasi pengunduhan), maka Anda harus menentukan kelas turunan dari ProgressChangedEventArgs.
Perhatikan bahwa hanya ada satu ProgressChanged atau peristiwa MethodNameProgressChanged untuk kelas, terlepas dari jumlah metode asinkron yang didukungnya. Klien diharapkan menggunakan userState objek yang diteruskan ke metode MethodNameAsync untuk membedakan antara pembaruan kemajuan pada beberapa operasi bersamaan.
Mungkin ada situasi di mana beberapa operasi memfasilitasi kemajuan dan masing-masing memberikan indikator yang berbeda untuk kemajuan. Dalam hal ini, satu ProgressChanged acara tidaklah tepat, dan Anda mungkin mempertimbangkan mendukung beberapa ProgressChanged acara. Dalam hal ini gunakan pola penamaan MethodNameProgressChanged untuk setiap metode MethodNameAsync .
Mematuhi semantik pelaporan kemajuan yang dijelaskan Praktik Terbaik untuk Menerapkan Pola Asinkron berbasis Peristiwa.
Secara opsional Berikan Dukungan untuk Mengembalikan Hasil Bertahap
Terkadang operasi asinkron dapat mengembalikan hasil inkremental sebelum penyelesaian. Ada sejumlah opsi yang dapat digunakan untuk mendukung skenario ini. Berikut adalah beberapa contoh.
Kelas Operasi Tunggal
Jika kelas Anda hanya mendukung satu operasi asinkron, dan operasi tersebut dapat mengembalikan hasil inkremental, maka:
Perluas jenis ProgressChangedEventArgs untuk membawa data hasil inkremental, dan tentukan sebuah peristiwa MethodNameProgressChanged dengan data yang telah diperluas ini.
Aktifkan peristiwa MethodNameProgressChanged ini saat ada hasil sementara yang perlu dilaporkan.
Solusi ini berlaku khusus untuk kelas operasi asinkron tunggal karena tidak ada masalah dengan peristiwa yang sama yang terjadi untuk mengembalikan hasil inkremental pada "semua operasi", seperti yang dilakukan peristiwa MethodNameProgressChanged .
Kelas Multi Operasi dengan Hasil Bertahap Homogen
Dalam hal ini, kelas Anda mendukung beberapa metode asinkron, masing-masing mampu mengembalikan hasil bertahap, dan hasil inkremental ini semuanya memiliki jenis data yang sama.
Ikuti model yang dijelaskan di atas untuk kelas operasi tunggal, karena struktur yang sama EventArgs akan berfungsi untuk semua hasil bertahap. Definisikan peristiwa ProgressChanged alih-alih peristiwa MethodNameProgressChanged, karena berlaku untuk beberapa metode asinkron.
Kelas Multi-operasi dengan Hasil Inkremental Heterogen
Jika kelas Anda mendukung beberapa metode asinkron, masing-masing mengembalikan jenis data yang berbeda, Anda harus:
Pisahkan pelaporan hasil inkremental Anda dari pelaporan kemajuan Anda.
Tentukan peristiwa MethodNameProgressChanged terpisah dengan EventArgs yang sesuai untuk setiap metode asinkron guna menangani data hasil bertahap dari metode tersebut.
Panggil penanganan aktivitas tersebut pada utas yang sesuai seperti yang dijelaskan dalam Praktik Terbaik untuk Menerapkan Pola Asinkron Berbasis Peristiwa.
Menangani Parameter Out dan Ref dalam Metode
Meskipun penggunaan out dan ref , secara umum, tidak disarankan dalam .NET, berikut adalah aturan yang harus diikuti ketika ada:
Diberikan metode sinkron MethodName:
outparameter ke MethodName tidak boleh menjadi bagian dari MethodNameAsync. Sebaliknya, mereka harus menjadi bagian dari MethodNameCompletedEventArgs dengan nama yang sama dengan parameternya yang setara dalam MethodName (kecuali ada nama yang lebih sesuai).refparameter ke MethodName akan muncul sebagai bagian dari MethodNameAsync, dan sebagai bagian dari MethodNameCompletedEventArgs dengan nama yang sama dengan parameternya yang setara dalam MethodName (kecuali ada nama yang lebih sesuai).
Misalnya, jika diberikan:
Public Function MethodName(ByVal arg1 As String, ByRef arg2 As String, ByRef arg3 As String) As Integer
public int MethodName(string arg1, ref string arg2, out string arg3);
Metode asinkron Anda dan kelasnya AsyncCompletedEventArgs akan terlihat seperti ini:
Public Sub MethodNameAsync(ByVal arg1 As String, ByVal arg2 As String)
Public Class MethodNameCompletedEventArgs
Inherits System.ComponentModel.AsyncCompletedEventArgs
Public ReadOnly Property Result() As Integer
End Property
Public ReadOnly Property Arg2() As String
End Property
Public ReadOnly Property Arg3() As String
End Property
End Class
public void MethodNameAsync(string arg1, string arg2);
public class MethodNameCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
public int Result { get; };
public string Arg2 { get; };
public string Arg3 { get; };
}
Lihat juga
- ProgressChangedEventArgs
- AsyncCompletedEventArgs
- Cara: Menerapkan Komponen yang Mendukung Pola Asinkron Berbasis Peristiwa
- Cara Menjalankan Operasi di Latar Belakang
- Cara Menerapkan Formulir yang Menggunakan Operasi Latar Belakang
- Memutuskan Kapan Harus Menerapkan Pola Asinkron Berbasis Peristiwa
- Praktik Terbaik untuk Menerapkan Pola Asinkron Berbasis Peristiwa
- Pola Asinkron Berbasis Peristiwa (EAP)