Menangani Reentrancy di Aplikasi Asinkron (Visual Basic)
Ketika Anda menyertakan kode asinkron di aplikasi Anda, Anda harus mempertimbangkan dan mungkin mencegah reentrancy, yang mengacu pada masuknya kembali operasi asinkron sebelum selesai. Jika Anda tidak mengidentifikasi dan menangani kemungkinan untuk reentrancy, itu dapat menyebabkan hasil yang tidak terduga.
Catatan
Untuk menjalankan contoh, Anda harus memiliki Visual Studio 2012 atau yang lebih baru dan .NET Framework 4.5 atau yang lebih baru yang terpasang di komputer Anda.
Catatan
Keamanan Lapisan Transportasi (TLS) versi 1.2 sekarang menjadi versi minimum untuk digunakan dalam pengembangan aplikasi Anda. Jika aplikasi Anda menargetkan versi .NET Framework yang lebih lama dari 4.7, lihat artikel berikut untuk praktik terbaik Keamanan Lapisan Transportasi (TLS) dengan .NET Framework.
Mengenali Reentrancy
Dalam contoh dalam topik ini, pengguna memilih tombol Mulai untuk memulai aplikasi asinkron yang mengunduh serangkaian situs web dan menghitung jumlah total byte yang diunduh. Versi sinkron dari contoh akan merespons dengan cara yang sama terlepas dari berapa kali pengguna memilih tombol karena, setelah pertama kali, utas UI mengabaikan peristiwa tersebut sampai aplikasi selesai berjalan. Namun, dalam aplikasi asinkron, utas UI terus merespons, dan Anda mungkin masuk kembali ke operasi asinkron sebelum selesai.
Contoh berikut menunjukkan output yang diharapkan jika pengguna memilih tombol Mulai hanya sekali. Daftar situs web yang diunduh muncul dengan ukuran, dalam byte, dari setiap situs. Jumlah total byte muncul di akhir.
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159
TOTAL bytes returned: 890591
Namun, jika pengguna memilih tombol lebih dari sekali, penanganan aktivitas dipanggil berulang kali, dan proses pengunduhan dimasukkan kembali setiap kali. Akibatnya, beberapa operasi asinkron berjalan pada saat yang sama, output menjalin hasil, dan jumlah total byte menjadi membingungkan.
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
6. msdn.microsoft.com/library/ms404677.aspx 197325
3. msdn.microsoft.com/library/jj155761.aspx 29019
7. msdn.microsoft.com 42972
4. msdn.microsoft.com/library/hh290140.aspx 117152
8. msdn.microsoft.com/library/ff730837.aspx 146159
TOTAL bytes returned: 890591
5. msdn.microsoft.com/library/hh524395.aspx 68959
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
6. msdn.microsoft.com/library/ms404677.aspx 197325
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
7. msdn.microsoft.com 42972
5. msdn.microsoft.com/library/hh524395.aspx 68959
8. msdn.microsoft.com/library/ff730837.aspx 146159
TOTAL bytes returned: 890591
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159
TOTAL bytes returned: 890591
Anda dapat meninjau kode yang menghasilkan output ini dengan menggulir ke akhir topik ini. Anda dapat bereksperimen dengan kode dengan mengunduh solusi ke komputer lokal Anda lalu menjalankan proyek WebsiteDownload atau dengan menggunakan kode di akhir topik ini untuk membuat proyek Anda sendiri Untuk informasi dan instruksi selengkapnya, lihat Meninjau dan Menjalankan Aplikasi Contoh.
Menangani Reentrancy
Anda dapat menangani reentrancy dengan berbagai cara, tergantung pada apa yang Anda inginkan untuk dilakukan aplikasi Anda. Topik ini menyajikan contoh berikut:
-
Nonaktifkan tombol Mulai saat operasi berjalan sehingga pengguna tidak dapat mengganggunya.
Batalkan dan Mulai Ulang Operasi
Batalkan operasi apa pun yang masih berjalan saat pengguna memilih tombol Mulai lagi, lalu biarkan operasi yang terakhir diminta berlanjut.
Jalankan Beberapa Operasi dan Antre Output
Izinkan semua operasi yang diminta berjalan secara asinkron, tetapi koordinasikan tampilan output sehingga hasil dari setiap operasi muncul bersama dan berurutan.
Nonaktifkan Tombol Mulai
Anda dapat memblokir tombol Mulai saat operasi berjalan dengan menonaktifkan tombol di bagian StartButton_Click
atas penanganan aktivitas. Anda kemudian dapat mengaktifkan kembali tombol dari dalam Finally
pemblokiran ketika operasi selesai sehingga pengguna dapat menjalankan aplikasi lagi.
Kode berikut menunjukkan perubahan ini, yang ditandai dengan tanda bintang. Anda dapat menambahkan perubahan pada kode di akhir topik ini, atau Anda dapat mengunduh aplikasi yang sudah jadi dari Sampel Asinkron: Reentrancy di Aplikasi Desktop .NET. Nama proyeknya adalah DisableStartButton.
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
' This line is commented out to make the results clearer in the output.
'ResultsTextBox.Text = ""
' ***Disable the Start button until the downloads are complete.
StartButton.IsEnabled = False
Try
Await AccessTheWebAsync()
Catch ex As Exception
ResultsTextBox.Text &= vbCrLf & "Downloads failed."
' ***Enable the Start button in case you want to run the program again.
Finally
StartButton.IsEnabled = True
End Try
End Sub
Akibat perubahan tersebut, tombol tidak merespons saat AccessTheWebAsync
mengunduh situs web, sehingga prosesnya tidak dapat dimasukkan kembali.
Batalkan dan Mulai Ulang Operasi
Alih-alih menonaktifkan tombol Mulai, Anda dapat menjaga tombol tetap aktif tetapi, jika pengguna memilih tombol itu lagi, batalkan operasi yang sudah berjalan dan biarkan operasi yang terakhir dimulai berlanjut.
Untuk informasi selengkapnya tentang pembatalan, lihat Menyempurnakan Aplikasi Asinkron Anda (Visual Basic).
Untuk menyiapkan skenario ini, buat perubahan berikut pada kode dasar yang disediakan dalam Meninjau dan Menjalankan Aplikasi Contoh. Anda juga dapat mengunduh aplikasi yang sudah jadi dari Async Samples: Reentrancy di Aplikasi Desktop .NET. Nama proyek ini adalah CancelAndRestart.
Deklarasikan variabel CancellationTokenSource,
cts
, yang berada dalam cakupan untuk semua metode.Class MainWindow // Or Class MainPage ' *** Declare a System.Threading.CancellationTokenSource. Dim cts As CancellationTokenSource
Pada
StartButton_Click
, tentukan apakah operasi sudah berlangsung. Jika nilaicts
adalahNothing
, tidak ada operasi yang sudah aktif. Jika nilainya bukanNothing
, operasi yang sudah berjalan dibatalkan.' *** If a download process is already underway, cancel it. If cts IsNot Nothing Then cts.Cancel() End If
Atur
cts
ke nilai berbeda yang mewakili proses saat ini.' *** Now set cts to cancel the current process if the button is chosen again. Dim newCTS As CancellationTokenSource = New CancellationTokenSource() cts = newCTS
Pada akhir
StartButton_Click
, proses saat ini selesai, jadi atur nilaicts
kembali keNothing
.' *** When the process completes, signal that another process can proceed. If cts Is newCTS Then cts = Nothing End If
Kode berikut menunjukkan semua perubahan dalam StartButton_Click
. Penambahan ditandai dengan tanda bintang.
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
' This line is commented out to make the results clearer.
'ResultsTextBox.Text = ""
' *** If a download process is underway, cancel it.
If cts IsNot Nothing Then
cts.Cancel()
End If
' *** Now set cts to cancel the current process if the button is chosen again.
Dim newCTS As CancellationTokenSource = New CancellationTokenSource()
cts = newCTS
Try
' *** Send a token to carry the message if the operation is canceled.
Await AccessTheWebAsync(cts.Token)
Catch ex As OperationCanceledException
ResultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf
Catch ex As Exception
ResultsTextBox.Text &= vbCrLf & "Downloads failed."
End Try
' *** When the process is complete, signal that another process can proceed.
If cts Is newCTS Then
cts = Nothing
End If
End Sub
Pada AccessTheWebAsync
, buat perubahan berikut.
Tambahkan parameter untuk menerima token pembatalan dari
StartButton_Click
.Gunakan metode GetAsync untuk mengunduh situs web karena
GetAsync
menerima argumen CancellationToken.Sebelum memanggil
DisplayResults
untuk menampilkan hasil untuk setiap situs web yang diunduh, periksact
untuk memverifikasi bahwa operasi saat ini tidak dibatalkan.
Kode berikut menunjukkan perubahan ini, yang ditandai dengan tanda bintang.
' *** Provide a parameter for the CancellationToken from StartButton_Click.
Private Async Function AccessTheWebAsync(ct As CancellationToken) As Task
' Declare an HttpClient object.
Dim client = New HttpClient()
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
Dim total = 0
Dim position = 0
For Each url In urlList
' *** Use the HttpClient.GetAsync method because it accepts a
' cancellation token.
Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)
' *** Retrieve the website contents from the HttpResponseMessage.
Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
' *** Check for cancellations before displaying information about the
' latest site.
ct.ThrowIfCancellationRequested()
position += 1
DisplayResults(url, urlContents, position)
' Update the total.
total += urlContents.Length
Next
' Display the total count for all of the websites.
ResultsTextBox.Text &=
String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned: " & total & vbCrLf)
End Function
Jika Anda memilih tombol Mulai beberapa kali saat aplikasi ini berjalan, itu harus menghasilkan hasil yang menyerupai output berikut:
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 122505
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
Download canceled.
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
Download canceled.
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159
TOTAL bytes returned: 890591
Untuk menghilangkan daftar parsial, hapus komentar baris pertama kode untuk StartButton_Click
menghapus kotak teks setiap kali pengguna memulai ulang operasi.
Jalankan Beberapa Operasi dan Antre Output
Contoh ketiga ini adalah yang paling rumit karena aplikasi memulai operasi asinkron lain setiap kali pengguna memilih tombol Mulai, dan semua operasi berjalan hingga selesai. Semua operasi yang diminta mengunduh situs web dari daftar secara asinkron, tetapi output dari operasi disajikan secara berurutan. Artinya, aktivitas pengunduhan yang sebenarnya diselingi, seperti yang ditunjukkan oleh output dalam Mengenali Reentrancy, tetapi daftar hasil untuk setiap grup disajikan secara terpisah.
Operasi berbagi Taskglobal, pendingWork
, yang berfungsi sebagai penjaga gerbang untuk proses tampilan.
Anda dapat menjalankan contoh ini dengan menempelkan perubahan ke dalam kode di Membangun Aplikasi, atau Anda dapat mengikuti instruksi di Mengunduh Aplikasi untuk mengunduh sampel lalu menjalankan proyek QueueResults.
Output berikut menunjukkan hasilnya jika pengguna memilih tombol Mulai hanya sekali. Label huruf, A, menunjukkan bahwa hasilnya adalah dari pertama kali tombol Mulai dipilih. Angka-angka menunjukkan urutan URL dalam daftar target unduhan.
#Starting group A.
#Task assigned for group A.
A-1. msdn.microsoft.com/library/hh191443.aspx 87389
A-2. msdn.microsoft.com/library/aa578028.aspx 209858
A-3. msdn.microsoft.com/library/jj155761.aspx 30870
A-4. msdn.microsoft.com/library/hh290140.aspx 119027
A-5. msdn.microsoft.com/library/hh524395.aspx 71260
A-6. msdn.microsoft.com/library/ms404677.aspx 199186
A-7. msdn.microsoft.com 53266
A-8. msdn.microsoft.com/library/ff730837.aspx 148020
TOTAL bytes returned: 918876
#Group A is complete.
Jika pengguna memilih tombol Mulai tiga kali, aplikasi menghasilkan output yang menyerupai baris berikut. Baris informasi yang dimulai dengan tanda pagar (#) melacak kemajuan aplikasi.
#Starting group A.
#Task assigned for group A.
A-1. msdn.microsoft.com/library/hh191443.aspx 87389
A-2. msdn.microsoft.com/library/aa578028.aspx 207089
A-3. msdn.microsoft.com/library/jj155761.aspx 30870
A-4. msdn.microsoft.com/library/hh290140.aspx 119027
A-5. msdn.microsoft.com/library/hh524395.aspx 71259
A-6. msdn.microsoft.com/library/ms404677.aspx 199185
#Starting group B.
#Task assigned for group B.
A-7. msdn.microsoft.com 53266
#Starting group C.
#Task assigned for group C.
A-8. msdn.microsoft.com/library/ff730837.aspx 148010
TOTAL bytes returned: 916095
B-1. msdn.microsoft.com/library/hh191443.aspx 87389
B-2. msdn.microsoft.com/library/aa578028.aspx 207089
B-3. msdn.microsoft.com/library/jj155761.aspx 30870
B-4. msdn.microsoft.com/library/hh290140.aspx 119027
B-5. msdn.microsoft.com/library/hh524395.aspx 71260
B-6. msdn.microsoft.com/library/ms404677.aspx 199186
#Group A is complete.
B-7. msdn.microsoft.com 53266
B-8. msdn.microsoft.com/library/ff730837.aspx 148010
TOTAL bytes returned: 916097
C-1. msdn.microsoft.com/library/hh191443.aspx 87389
C-2. msdn.microsoft.com/library/aa578028.aspx 207089
#Group B is complete.
C-3. msdn.microsoft.com/library/jj155761.aspx 30870
C-4. msdn.microsoft.com/library/hh290140.aspx 119027
C-5. msdn.microsoft.com/library/hh524395.aspx 72765
C-6. msdn.microsoft.com/library/ms404677.aspx 199186
C-7. msdn.microsoft.com 56190
C-8. msdn.microsoft.com/library/ff730837.aspx 148010
TOTAL bytes returned: 920526
#Group C is complete.
Grup B dan grup C dimulai sebelum grup A selesai, tetapi output untuk setiap grup muncul secara terpisah. Semua output untuk grup A muncul terlebih dahulu, diikuti oleh semua output untuk grup B, lalu semua output untuk grup C. Aplikasi ini selalu menampilkan grup secara berurutan dan, untuk setiap grup, selalu menampilkan informasi tentang masing-masing situs web agar URL muncul dalam daftar URL.
Namun, Anda tidak dapat memprediksi urutan di mana unduhan benar-benar terjadi. Setelah beberapa grup dimulai, tugas unduhan yang dihasilkan semuanya aktif. Anda tidak dapat berasumsi bahwa A-1 akan diunduh sebelum B-1, dan Anda tidak dapat berasumsi bahwa A-1 akan diunduh sebelum A-2.
Definisi Global
Kode sampel berisi dua deklarasi global berikut yang dapat terlihat dari semua metode.
Class MainWindow ' Class MainPage in Windows Store app.
' ***Declare the following variables where all methods can access them.
Private pendingWork As Task = Nothing
Private group As Char = ChrW(AscW("A") - 1)
Variabel Task
, pendingWork
, mengawasi proses tampilan dan mencegah grup apa pun mengganggu operasi tampilan grup lain. Variabel karakter, group
, melabeli output dari grup yang berbeda untuk memverifikasi bahwa hasil muncul dalam urutan yang diharapkan.
Penanganan Aktivitas Klik
Penanganan aktivitas, StartButton_Click
, menaikkan huruf grup setiap kali pengguna memilih tombol Mulai. Kemudian penanganan memanggil AccessTheWebAsync
untuk menjalankan operasi pengunduhan.
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
' ***Verify that each group's results are displayed together, and that
' the groups display in order, by marking each group with a letter.
group = ChrW(AscW(group) + 1)
ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "#Starting group {0}.", group)
Try
' *** Pass the group value to AccessTheWebAsync.
Dim finishedGroup As Char = Await AccessTheWebAsync(group)
' The following line verifies a successful return from the download and
' display procedures.
ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "#Group {0} is complete." & vbCrLf, finishedGroup)
Catch ex As Exception
ResultsTextBox.Text &= vbCrLf & "Downloads failed."
End Try
End Sub
Metode AccessTheWebAsync
Contoh ini dibagi AccessTheWebAsync
menjadi dua metode. Metode pertama, AccessTheWebAsync
, memulai semua tugas unduhan untuk grup dan menyiapkan pendingWork
untuk mengontrol proses tampilan. Metode ini menggunakan Language Integrated Query (kueri LINQ) dan ToArray untuk memulai semua tugas unduhan secara bersamaan.
AccessTheWebAsync
kemudian memanggil FinishOneGroupAsync
untuk menunggu penyelesaian setiap unduhan dan menampilkan panjangnya.
FinishOneGroupAsync
mengembalikan tugas yang ditetapkan pada pendingWork
dalam AccessTheWebAsync
. Nilai itu mencegah gangguan oleh operasi lain sebelum tugas selesai.
Private Async Function AccessTheWebAsync(grp As Char) As Task(Of Char)
Dim client = New HttpClient()
' Make a list of the web addresses to download.
Dim urlList As List(Of String) = SetUpURLList()
' ***Kick off the downloads. The application of ToArray activates all the download tasks.
Dim getContentTasks As Task(Of Byte())() =
urlList.Select(Function(addr) client.GetByteArrayAsync(addr)).ToArray()
' ***Call the method that awaits the downloads and displays the results.
' Assign the Task that FinishOneGroupAsync returns to the gatekeeper task, pendingWork.
pendingWork = FinishOneGroupAsync(urlList, getContentTasks, grp)
ResultsTextBox.Text &=
String.Format(vbCrLf & "#Task assigned for group {0}. Download tasks are active." & vbCrLf, grp)
' ***This task is complete when a group has finished downloading and displaying.
Await pendingWork
' You can do other work here or just return.
Return grp
End Function
Metode FinishOneGroupAsync
Metode ini menelusuri tugas unduhan dalam grup, menunggu masing-masing tugas, menampilkan panjang situs web yang diunduh, dan menambahkan panjang secara keseluruhan.
Pernyataan pertama dalam FinishOneGroupAsync
menggunakan pendingWork
untuk memastikan bahwa memasukkan metode tidak mengganggu operasi yang sudah dalam proses tampilan atau yang sudah menunggu. Jika operasi seperti itu sedang berlangsung, operasi masuk harus menunggu gilirannya.
Private Async Function FinishOneGroupAsync(urls As List(Of String), contentTasks As Task(Of Byte())(), grp As Char) As Task
' Wait for the previous group to finish displaying results.
If pendingWork IsNot Nothing Then
Await pendingWork
End If
Dim total = 0
' contentTasks is the array of Tasks that was created in AccessTheWebAsync.
For i As Integer = 0 To contentTasks.Length - 1
' Await the download of a particular URL, and then display the URL and
' its length.
Dim content As Byte() = Await contentTasks(i)
DisplayResults(urls(i), content, i, grp)
total += content.Length
Next
' Display the total count for all of the websites.
ResultsTextBox.Text &=
String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned: " & total & vbCrLf)
End Function
Anda dapat menjalankan contoh ini dengan menempelkan perubahan pada kode dalam Membangun Aplikasi, atau Anda dapat mengikuti instruksi dalam Mengunduh Aplikasi untuk mengunduh sampel, lalu menjalankan proyek QueueResults.
Poin Yang Perlu Diperhatikan
Jalur informasi yang dimulai dengan tanda pagar (#) dalam output yang memperjelas cara kerja contoh ini.
Output menunjukkan pola berikut.
Grup dapat dimulai saat grup sebelumnya menampilkan outputnya, tetapi tampilan output grup sebelumnya tidak terganggu.
#Starting group A. #Task assigned for group A. Download tasks are active. A-1. msdn.microsoft.com/library/hh191443.aspx 87389 A-2. msdn.microsoft.com/library/aa578028.aspx 207089 A-3. msdn.microsoft.com/library/jj155761.aspx 30870 A-4. msdn.microsoft.com/library/hh290140.aspx 119037 A-5. msdn.microsoft.com/library/hh524395.aspx 71260 #Starting group B. #Task assigned for group B. Download tasks are active. A-6. msdn.microsoft.com/library/ms404677.aspx 199186 A-7. msdn.microsoft.com 53078 A-8. msdn.microsoft.com/library/ff730837.aspx 148010 TOTAL bytes returned: 915919 B-1. msdn.microsoft.com/library/hh191443.aspx 87388 B-2. msdn.microsoft.com/library/aa578028.aspx 207089 B-3. msdn.microsoft.com/library/jj155761.aspx 30870 #Group A is complete. B-4. msdn.microsoft.com/library/hh290140.aspx 119027 B-5. msdn.microsoft.com/library/hh524395.aspx 71260 B-6. msdn.microsoft.com/library/ms404677.aspx 199186 B-7. msdn.microsoft.com 53078 B-8. msdn.microsoft.com/library/ff730837.aspx 148010 TOTAL bytes returned: 915908
Tugas
pendingWork
adalahNothing
pada permulaanFinishOneGroupAsync
hanya untuk grup A, yang dimulai terlebih dahulu. Grup A belum menyelesaikan ekspresi tunggu saat mencapaiFinishOneGroupAsync
. Oleh karena itu, kontrol belum kembali keAccessTheWebAsync
, dan tugaspendingWork
pertama belum terjadi.Dua baris berikut selalu muncul bersama-sama dalam output. Kode tidak pernah terputus antara memulai operasi grup di
StartButton_Click
dan menetapkan tugas untuk grup padapendingWork
.#Starting group B. #Task assigned for group B. Download tasks are active.
Setelah grup memasuki
StartButton_Click
, operasi tidak menyelesaikan ekspresi tunggu hingga operasi memasukiFinishOneGroupAsync
. Oleh karena itu, tidak ada operasi lain yang dapat memperoleh kontrol selama segmen kode tersebut.
Meninjau dan Menjalankan Aplikasi Contoh
Untuk lebih memahami aplikasi contoh, Anda dapat mengunduhnya, membuatnya sendiri, atau meninjau kode di akhir topik ini tanpa menerapkan aplikasi.
Catatan
Untuk menjalankan contoh sebagai aplikasi desktop Windows Presentation Foundation (WPF), Anda harus memiliki Visual Studio 2012 atau yang lebih baru dan .NET Framework 4.5 atau yang lebih baru terpasang pada komputer Anda.
Mengunduh Aplikasi
Unduh file terkompresi dari Sampel Asinkron: Reentrancy di Aplikasi Desktop .NET.
Dekompresi file yang Anda unduh, lalu mulai Visual Studio.
Pada bilah menu, pilih File, Buka, Project/Solusi.
Navigasikan ke folder yang menyimpan kode sampel yang didekompresi, lalu buka file solusi (.sln).
Di Penjelajah Solusi, buka menu pintasan untuk proyek yang ingin Anda jalankan, lalu pilih Atur sebagai StartUpProject.
Pilih tombol CTRL+F5 untuk membangun dan menjalankan proyek.
Membangun Aplikasi
Bagian berikut memberikan kode untuk membangun contoh sebagai aplikasi WPF.
Untuk membangun aplikasi WPF
Mulai Visual Studio.
Di bilah menu, pilih File, Baru, Proyek.
Kotak dialog Proyek Baru terbuka.
Di panel Templat terpasang, perluas Visual Basic, lalu perluas Windows.
Dalam daftar jenis proyek, pilih Aplikasi WPF.
Beri nama proyek
WebsiteDownloadWPF
, pilih versi .NET Framework 4.6 atau yang lebih tinggi lalu klik tombol OK.Proyek baru muncul di Penjelajah Solusi.
Di editor Visual Studio Code, pilih tab MainWindow.xaml.
Jika tab tidak terlihat, buka menu pintasan untuk MainWindow.xaml di Penjelajah Solusi, lalu pilih Tampilkan Kode.
Dalam tampilan XAML MainWindow.xaml, ganti kode dengan kode berikut.
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:WebsiteDownloadWPF" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Width="517" Height="360"> <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="-1,0,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="53" Background="#FFA89B9B" FontSize="36" Width="518" /> <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="-1,53,0,-36" TextWrapping="Wrap" VerticalAlignment="Top" Height="343" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="518" FontFamily="Lucida Console" /> </Grid> </Window>
Jendela sederhana yang berisi kotak teks dan tombol muncul dalam tampilan Desain MainWindow.xaml.
Di Penjelajah Solusi, klik kanan Referensi dan pilih Tambahkan Referensi.
Tambahkan referensi untuk System.Net.Http, jika belum dipilih.
Di Penjelajah Solusi, buka menu pintasan untuk MainWindow.xaml.vb, lalu pilih Tampilkan Kode.
Di MainWindow.xaml.vb , ganti kode dengan kode berikut.
' Add the following Imports statements, and add a reference for System.Net.Http. Imports System.Net.Http Imports System.Threading Class MainWindow Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol Or System.Net.SecurityProtocolType.Tls12 ' This line is commented out to make the results clearer in the output. 'ResultsTextBox.Text = "" Try Await AccessTheWebAsync() Catch ex As Exception ResultsTextBox.Text &= vbCrLf & "Downloads failed." End Try End Sub Private Async Function AccessTheWebAsync() As Task ' Declare an HttpClient object. Dim client = New HttpClient() ' Make a list of web addresses. Dim urlList As List(Of String) = SetUpURLList() Dim total = 0 Dim position = 0 For Each url In urlList ' GetByteArrayAsync returns a task. At completion, the task ' produces a byte array. Dim urlContents As Byte() = Await client.GetByteArrayAsync(url) position += 1 DisplayResults(url, urlContents, position) ' Update the total. total += urlContents.Length Next ' Display the total count for all of the websites. ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned: " & total & vbCrLf) End Function Private Function SetUpURLList() As List(Of String) Dim urls = New List(Of String) From { "https://msdn.microsoft.com/library/hh191443.aspx", "https://msdn.microsoft.com/library/aa578028.aspx", "https://msdn.microsoft.com/library/jj155761.aspx", "https://msdn.microsoft.com/library/hh290140.aspx", "https://msdn.microsoft.com/library/hh524395.aspx", "https://msdn.microsoft.com/library/ms404677.aspx", "https://msdn.microsoft.com", "https://msdn.microsoft.com/library/ff730837.aspx" } Return urls End Function Private Sub DisplayResults(url As String, content As Byte(), pos As Integer) ' Display the length of each website. The string format is designed ' to be used with a monospaced font, such as Lucida Console or ' Global Monospace. ' Strip off the "http:'". Dim displayURL = url.Replace("https://", "") ' Display position in the URL list, the URL, and the number of bytes. ResultsTextBox.Text &= String.Format(vbCrLf & "{0}. {1,-58} {2,8}", pos, displayURL, content.Length) End Sub End Class
Pilih tombol CTRL+F5 untuk menjalankan program, lalu pilih tombol Mulai beberapa kali.
Buat perubahan dari Nonaktifkan Tombol Mulai, Batalkan dan Mulai Ulang Operasi, atau Jalankan Beberapa Operasi dan Antre Output untuk menangani reentrancy.
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk