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.
Anda dapat menghindari penyempitan performa dan meningkatkan respons keseluruhan aplikasi Anda dengan menggunakan pemrograman asinkron. Namun, teknik tradisional untuk menulis aplikasi asinkron bisa rumit, membuatnya sulit ditulis, di-debug, dan dipertahankan.
Visual Studio 2012 memperkenalkan pendekatan yang disederhanakan, pemrograman asinkron, yang memanfaatkan dukungan asinkron dalam .NET Framework 4.5 dan yang lebih tinggi serta di Windows Runtime. Pengompilasi melakukan pekerjaan sulit yang biasa dilakukan pengembang, dan aplikasi Anda mempertahankan struktur logis yang menyerupai kode sinkron. Akibatnya, Anda mendapatkan semua keuntungan dari pemrograman asinkron dengan sebagian kecil dari upaya.
Topik ini memberikan gambaran umum tentang kapan dan bagaimana menggunakan pemrograman asinkron dan menyertakan tautan ke topik dukungan yang berisi detail dan contoh.
Asinkron meningkatkan responsivitas
Asinkron sangat penting untuk aktivitas yang berpotensi memblokir, seperti ketika aplikasi Anda mengakses web. Akses ke sumber daya web terkadang lambat atau tertunda. Jika aktivitas seperti itu diblokir dalam proses sinkron, seluruh aplikasi harus menunggu. Dalam proses asinkron, aplikasi dapat dilanjutkan dengan pekerjaan lain yang tidak bergantung pada sumber daya web sampai tugas yang berpotensi memblokir selesai.
Tabel berikut menunjukkan area umum di mana pemrograman asinkron meningkatkan responsivitas. API yang tercantum dari .NET Framework 4.5 dan Windows Runtime berisi metode yang mendukung pemrograman asinkron.
Area aplikasi | API pendukung yang berisi metode asinkron |
---|---|
Akses web | HttpClient, SyndicationClient |
Bekerja dengan berkas | StorageFile,StreamWriter,StreamReader,XmlReader |
Bekerja dengan gambar | MediaCapture, , BitmapEncoderBitmapDecoder |
Pemrograman WCF | Operasi Sinkron dan Asinkron |
Asinkron terbukti sangat berharga bagi aplikasi yang mengakses utas UI karena semua aktivitas terkait UI biasanya berbagi satu utas. Jika ada proses yang diblokir dalam aplikasi sinkron, semua diblokir. Aplikasi Anda berhenti merespons, dan Anda mungkin menyimpulkan bahwa aplikasi tersebut gagal, padahal sebenarnya hanya sedang menunggu.
Saat Anda menggunakan metode asinkron, aplikasi terus merespons UI. Anda dapat mengubah ukuran atau meminimalkan jendela, misalnya, atau Anda dapat menutup aplikasi jika Anda tidak ingin menunggunya selesai.
Pendekatan berbasis asinkron menambahkan transmisi otomatis yang setara dengan daftar opsi yang dapat Anda pilih saat merancang operasi asinkron. Artinya, Anda mendapatkan semua manfaat pemrograman asinkron tradisional tetapi dengan upaya yang jauh lebih sedikit dari pengembang.
Metode asinkron lebih mudah ditulis
Kata kunci Asinkron dan Tunggu di Visual Basic adalah inti dari pemrograman asinkron. Dengan menggunakan kedua kata kunci tersebut, Anda dapat menggunakan sumber daya di .NET Framework atau Windows Runtime untuk membuat metode asinkron hampir semampu Anda membuat metode sinkron. Metode asinkron yang Anda tentukan dengan menggunakan Async
dan Await
disebut sebagai metode asinkron.
Contoh berikut menunjukkan metode asinkron. Hampir semua yang ada dalam kode akan terlihat sangat akrab untuk Anda. Komentar menyebut fitur yang Anda tambahkan untuk menciptakan asinkroni.
Anda dapat menemukan file contoh Windows Presentation Foundation (WPF) lengkap di akhir topik ini, dan Anda dapat mengunduh sampel dari Sampel Asinkron: Contoh dari "Pemrograman Asinkron dengan Asinkron dan Menunggu".
' Three things to note about writing an Async Function:
' - The function has an Async modifier.
' - Its return type is Task or Task(Of T). (See "Return Types" section.)
' - As a matter of convention, its name ends in "Async".
Async Function AccessTheWebAsync() As Task(Of Integer)
Using client As New HttpClient()
' Call and await separately.
' - AccessTheWebAsync can do other things while GetStringAsync is also running.
' - getStringTask stores the task we get from the call to GetStringAsync.
' - Task(Of String) means it is a task which returns a String when it is done.
Dim getStringTask As Task(Of String) =
client.GetStringAsync("https://learn.microsoft.com/dotnet")
' You can do other work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork()
' The Await operator suspends AccessTheWebAsync.
' - AccessTheWebAsync does not continue until getStringTask is complete.
' - Meanwhile, control returns to the caller of AccessTheWebAsync.
' - Control resumes here when getStringTask is complete.
' - The Await operator then retrieves the String result from getStringTask.
Dim urlContents As String = Await getStringTask
' The Return statement specifies an Integer result.
' A method which awaits AccessTheWebAsync receives the Length value.
Return urlContents.Length
End Using
End Function
Jika AccessTheWebAsync
tidak memiliki pekerjaan apa pun yang dapat dilakukan antara memanggil GetStringAsync
dan menunggu penyelesaiannya, Anda dapat menyederhanakan kode Anda dengan memanggil dan menunggu dalam satu pernyataan berikut.
Dim urlContents As String = Await client.GetStringAsync()
Karakteristik berikut meringkas apa yang membuat contoh sebelumnya sebagai metode asinkron:
Definisi metode mencakup pengubah
Async
.Nama metode asinkron, menurut konvensi, diakhiri dengan akhiran "Asinkron".
Jenis pengembalian adalah salah satu jenis berikut:
- Task(Of TResult) jika metode Anda memiliki pernyataan pengembalian di mana operand memiliki jenis TResult.
- Task jika metode Anda tidak memiliki pernyataan pengembalian atau memiliki pernyataan pengembalian tanpa operand.
- Sub jika Anda menulis penanganan aktivitas asinkron.
Untuk informasi selengkapnya, lihat "Tipe Pengembalian dan Parameter" di bagian ini kemudian.
Metode ini biasanya mencakup setidaknya satu ekspresi tunggu, yang menandai titik di mana metode tidak dapat dilanjutkan sampai operasi asinkron yang ditunggu selesai. Sementara itu, metode ditangguhkan, dan kontrol kembali ke pemanggil metode. Bagian berikutnya dari topik ini menggambarkan apa yang terjadi pada titik penangguhan.
Dalam metode asinkron, Anda menggunakan kata kunci dan jenis yang disediakan untuk menunjukkan apa yang ingin Anda lakukan, dan pengkompilasi melakukan sisanya, termasuk melacak apa yang harus terjadi ketika kontrol kembali ke titik tunggu dalam metode yang ditangguhkan. Beberapa proses rutin, seperti perulangan dan penanganan pengecualian, bisa sulit ditangani dalam kode asinkron tradisional. Dalam metode asinkron, Anda menulis elemen-elemen ini sebanyak yang Anda lakukan dalam solusi sinkron, dan masalahnya diselesaikan.
Untuk informasi selengkapnya tentang asinkron di versi .NET Framework sebelumnya, lihat Pemrograman Asinkron TPL dan .NET Framework Tradisional.
Apa yang terjadi dalam metode Asinkron
Hal terpenting yang perlu dipahami dalam pemrograman asinkron adalah bagaimana alur kontrol berpindah dari metode ke metode. Diagram berikut mengarahkan Anda melalui proses:
Angka dalam diagram sesuai dengan langkah-langkah berikut:
Pengendali acara memanggil dan menunggu metode asinkron
AccessTheWebAsync
.AccessTheWebAsync
membuat instans HttpClient dan memanggil GetStringAsync metode asinkron untuk mengunduh konten situs web sebagai string.Sesuatu terjadi dalam
GetStringAsync
yang menangguhkan kemajuannya. Mungkin harus menunggu pengunduhan situs web atau aktivitas penghalang lainnya. Untuk menghindari pemblokiran sumber daya,GetStringAsync
menghasilkan kontrol kepada pemanggilnya,AccessTheWebAsync
.GetStringAsync
mengembalikan Task(Of TResult) di mana TResult adalah string, danAccessTheWebAsync
menetapkan tugas kegetStringTask
variabel. Tugas ini mewakili proses yang sedang berlangsung untuk panggilan keGetStringAsync
, dan memiliki komitmen untuk menghasilkan nilai string aktual ketika pekerjaan telah selesai.Karena
getStringTask
belum ditunggu,AccessTheWebAsync
dapat dilanjutkan dengan pekerjaan lain yang tidak bergantung pada hasil akhir dariGetStringAsync
. Pekerjaan itu diwakili oleh panggilan ke metode sinkronDoIndependentWork
.DoIndependentWork
adalah metode sinkron yang melakukan pekerjaannya dan kembali ke pemanggilnya.AccessTheWebAsync
telah kehabisan pekerjaan yang dapat dilakukannya tanpa hasil darigetStringTask
.AccessTheWebAsync
selanjutnya ingin menghitung dan mengembalikan panjang string yang diunduh, tetapi metode tidak dapat menghitung nilai tersebut sampai metode memiliki string.Oleh karena itu,
AccessTheWebAsync
menggunakan operator tunggu untuk menangguhkan eksekusinya dan mengalihkan kontrol ke metode yang memanggilAccessTheWebAsync
.AccessTheWebAsync
mengembalikanTask(Of Integer)
ke pemanggilnya. Tugas ini mewakili janji untuk menghasilkan hasil berupa bilangan bulat yang menunjukkan panjang string yang telah diunduh.Nota
Jika
GetStringAsync
(dan oleh karena itugetStringTask
) selesai sebelumAccessTheWebAsync
menunggunya, kontrol tetap berada diAccessTheWebAsync
. Biaya menangguhkan dan mengembalikan keAccessTheWebAsync
akan sia-sia jika proses asinkron yang disebut (getStringTask
) sudah selesai dan AccessTheWebSync tidak perlu menunggu hasil akhirnya.Di dalam pemanggil (penanganan aktivitas dalam contoh ini), pola pemrosesan berlanjut. Pemanggil mungkin melakukan pekerjaan lain yang tidak bergantung pada hasil dari
AccessTheWebAsync
sebelum menanti hasil tersebut, atau pemanggil mungkin langsung menanti. Penanganan aktivitas menungguAccessTheWebAsync
, danAccessTheWebAsync
sedang menungguGetStringAsync
.GetStringAsync
menyelesaikan dan menghasilkan hasil string. Hasil string tidak dikembalikan oleh panggilan keGetStringAsync
dengan cara yang mungkin Anda harapkan. (Ingat bahwa metode sudah mengembalikan tugas di langkah 3.) Sebaliknya, hasil string disimpan dalam tugas yang mewakili penyelesaian metode ,getStringTask
. Operator tunggu mengambil hasil darigetStringTask
. Pernyataan penugasan menetapkan hasil yang diambil keurlContents
.Ketika
AccessTheWebAsync
memiliki hasil string, metode dapat menghitung panjang string. Kemudian pekerjaanAccessTheWebAsync
juga selesai, dan penanganan aktivitas yang menunggu dapat dilanjutkan. Dalam contoh lengkap di akhir topik, Anda dapat mengonfirmasi bahwa penanganan aktivitas mengambil dan mencetak nilai hasil panjang.
Jika Anda baru menggunakan pemrograman asinkron, luangkan waktu satu menit untuk mempertimbangkan perbedaan antara perilaku sinkron dan asinkron. Metode sinkron kembali ketika pekerjaannya selesai (langkah 5), tetapi metode asinkron mengembalikan nilai tugas ketika pekerjaannya ditangguhkan (langkah 3 dan 6). Ketika metode asinkron akhirnya menyelesaikan pekerjaannya, tugas ditandai sebagai selesai dan hasilnya, jika ada, disimpan dalam tugas.
Untuk informasi selengkapnya tentang alur kontrol, lihat Alur Kontrol di Program Asinkron (Visual Basic).
Metode Asinkron API
Anda mungkin bertanya-tanya di mana menemukan metode seperti GetStringAsync
yang mendukung pemrograman asinkron. .NET Framework 4.5 atau yang lebih tinggi berisi banyak anggota yang bekerja dengan Async
dan Await
. Anda dapat mengenali anggota ini dengan akhiran "Async" yang dilampirkan ke nama anggota dan jenis Task pengembalian atau Task(Of TResult). Misalnya, System.IO.Stream
kelas berisi metode seperti CopyToAsync, , ReadAsyncdan WriteAsync bersama metode CopyTosinkron , , Readdan Write.
Windows Runtime juga berisi banyak metode yang dapat Anda gunakan dengan Async
dan Await
di aplikasi Windows. Untuk informasi selengkapnya dan contoh metode, lihat Memanggil API asinkron di C# atau Visual Basic, Pemrograman asinkron (aplikasi Windows Runtime), dan WhenAny: Menjembatani antara .NET Framework dan Windows Runtime.
Rangkaian Diskusi
Metode asinkron dimaksudkan sebagai operasi yang tidak memblokir. Ekspresi Await
dalam metode asinkron tidak memblokir utas saat ini saat tugas yang ditunggu sedang berjalan. Sebagai gantinya, ekspresi mendaftarkan sisa metode sebagai kelanjutan dan mengembalikan kontrol ke pemanggil metode asinkron.
Async
dan Await
tidak menyebabkan utas tambahan dibuat. Metode asinkron tidak memerlukan multi-utas karena metode asinkron tidak berjalan pada utasnya sendiri. Metode ini berjalan di konteks sinkronisasi saat ini dan memanfaatkan waktu pada utas hanya ketika metode aktif. Anda dapat menggunakan Task.Run untuk memindahkan pekerjaan yang terikat CPU ke utas latar belakang, tetapi utas latar belakang tidak membantu proses yang hanya menunggu hasil agar tersedia.
Pendekatan berbasis asinkron untuk pemrograman asinkron lebih disukai dibandingkan pendekatan yang ada dalam hampir setiap kasus. Secara khusus, pendekatan ini lebih baik daripada BackgroundWorker untuk operasi yang bergantung pada I/O karena kodenya lebih sederhana dan Anda tidak perlu menghindari kondisi balapan. Dalam kombinasi dengan Task.Run, pemrograman asinkron lebih baik daripada BackgroundWorker untuk operasi terikat CPU karena pemrograman asinkron memisahkan detail koordinasi dalam menjalankan kode Anda dari pekerjaan yang Task.Run
diteruskan ke threadpool.
Asinkron dan Await
Jika Anda menentukan bahwa metode adalah metode asinkron dengan menggunakan pengubah Asinkron , Anda mengaktifkan dua kemampuan berikut.
Metode asinkron yang ditandai dapat menggunakan Tunggu untuk menunjuk titik penangguhan. Operator tunggu memberi tahu pengompilasi bahwa metode asinkron tidak dapat melanjutkan melewati titik itu sampai proses asinkron yang ditunggu selesai. Sementara itu, pengendalian kembali ke pemanggil metode asinkron.
Penangguhan sementara metode asinkron pada ekspresi
Await
tidak berarti keluar dari metode, dan blok kodeFinally
tidak dijalankan.Metode asinkron yang ditandai dapat ditunggu oleh metode yang memanggilnya.
Metode asinkron biasanya berisi satu atau beberapa kemunculan Await
operator, tetapi tidak adanya Await
ekspresi tidak menyebabkan kesalahan kompilator. Jika metode asinkron tidak menggunakan operator Await
untuk menandai titik penangguhan, metode tersebut akan dijalankan seperti metode sinkron, meskipun dengan pengubah Async
. Kompilator mengeluarkan peringatan untuk metode tersebut.
Async
dan Await
adalah kata kunci kontekstual. Untuk informasi dan contoh selengkapnya, lihat topik berikut ini:
Jenis dan parameter pengembalian
Dalam pemrograman .NET Framework, metode asinkron biasanya mengembalikan Task atau Task(Of TResult). Di dalam metode async, operator Await
diterapkan pada task yang dikembalikan dari pemanggilan metode async lainnya.
Anda menentukan Tugas (Dari TResult) sebagai jenis pengembalian jika metode berisi pernyataan Return yang menentukan operand jenis TResult
.
Anda menggunakan Task
sebagai jenis pengembalian jika metode tidak memiliki pernyataan pengembalian atau memiliki pernyataan pengembalian yang tidak mengembalikan operand.
Contoh berikut menunjukkan cara Anda mendeklarasikan dan memanggil metode yang mengembalikan Task(Of TResult) atau Task:
' Signature specifies Task(Of Integer)
Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)
Dim hours As Integer
' . . .
' Return statement specifies an integer result.
Return hours
End Function
' Calls to TaskOfTResult_MethodAsync
Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
Dim intResult As Integer = Await returnedTaskTResult
' or, in a single statement
Dim intResult As Integer = Await TaskOfTResult_MethodAsync()
' Signature specifies Task
Async Function Task_MethodAsync() As Task
' . . .
' The method has no return statement.
End Function
' Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync()
Await returnedTask
' or, in a single statement
Await Task_MethodAsync()
Setiap tugas yang dikembalikan mewakili pekerjaan yang sedang berlangsung. Tugas merangkum informasi tentang status proses asinkron dan, akhirnya, memberikan hasil akhir dari proses atau pengecualian yang terjadi jika proses tidak berhasil.
Metode asinkron juga bisa menjadi Sub
metode. Jenis pengembalian ini digunakan terutama untuk menentukan penanganan aktivitas, di mana jenis pengembalian diperlukan. Penanganan aktivitas asinkron sering berfungsi sebagai titik awal untuk program asinkron.
Metode async yang merupakan Sub
prosedur tidak dapat dijeda/dinantikan, dan pemanggil tidak dapat menangkap pengecualian apa pun yang mungkin dilemparkan oleh metode tersebut.
Metode asinkron tidak dapat mendeklarasikan parameter ByRef , tetapi metode ini dapat memanggil metode yang memiliki parameter tersebut.
Untuk informasi dan contoh selengkapnya, lihat Tipe Pengembalian Asinkron (Visual Basic). Untuk informasi selengkapnya tentang cara menangkap pengecualian dalam metode asinkron, lihat Try...Catch...Finally Statement.
API asinkron dalam pemrograman Windows Runtime memiliki salah satu jenis pengembalian berikut, yang mirip dengan tugas:
- IAsyncOperation(Of TResult), yang sesuai dengan Task(Of TResult)
- IAsyncAction, yang sesuai dengan Task
- IAsyncActionWithProgress(Of TProgress)
- IAsyncOperationWithProgress(Of TResult, TProgress)
Untuk informasi selengkapnya dan contohnya, lihat Memanggil API asinkron di C# atau Visual Basic.
Konvensi penamaan
Menurut konvensi, Anda menambahkan "Asinkron" ke nama metode yang memiliki pengubah Async
.
Anda dapat mengabaikan konvensi di mana peristiwa, kelas dasar, atau kontrak antarmuka menyarankan nama yang berbeda. Misalnya, Anda tidak boleh mengganti nama penanganan aktivitas umum, seperti Button1_Click
.
Topik dan sampel terkait (Visual Studio)
Contoh Lengkap
Kode berikut adalah file MainWindow.xaml.vb dari aplikasi Windows Presentation Foundation (WPF) yang dibahas topik ini. Anda dapat mengunduh sampel dari Sampel Asinkron: Contoh dari "Pemrograman Asinkron dengan Asinkron dan Menunggu".
Imports System.Net.Http
' Example that demonstrates Asynchronous Programming with Async and Await.
' It uses HttpClient.GetStringAsync to download the contents of a website.
' Sample Output:
' Working . . . . . . .
'
' Length of the downloaded string: 39678.
Class MainWindow
' Mark the event handler with Async so you can use Await in it.
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
' Call and await immediately.
' StartButton_Click suspends until AccessTheWebAsync is done.
Dim contentLength As Integer = Await AccessTheWebAsync()
ResultsTextBox.Text &= $"{vbCrLf}Length of the downloaded string: {contentLength}.{vbCrLf}"
End Sub
' Three things to note about writing an Async Function:
' - The function has an Async modifier.
' - Its return type is Task or Task(Of T). (See "Return Types" section.)
' - As a matter of convention, its name ends in "Async".
Async Function AccessTheWebAsync() As Task(Of Integer)
Using client As New HttpClient()
' Call and await separately.
' - AccessTheWebAsync can do other things while GetStringAsync is also running.
' - getStringTask stores the task we get from the call to GetStringAsync.
' - Task(Of String) means it is a task which returns a String when it is done.
Dim getStringTask As Task(Of String) =
client.GetStringAsync("https://learn.microsoft.com/dotnet")
' You can do other work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork()
' The Await operator suspends AccessTheWebAsync.
' - AccessTheWebAsync does not continue until getStringTask is complete.
' - Meanwhile, control returns to the caller of AccessTheWebAsync.
' - Control resumes here when getStringTask is complete.
' - The Await operator then retrieves the String result from getStringTask.
Dim urlContents As String = Await getStringTask
' The Return statement specifies an Integer result.
' A method which awaits AccessTheWebAsync receives the Length value.
Return urlContents.Length
End Using
End Function
Sub DoIndependentWork()
ResultsTextBox.Text &= $"Working . . . . . . .{vbCrLf}"
End Sub
End Class