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.
Dengan menggunakan Task.WhenAny, Anda dapat memulai beberapa tugas secara bersamaan dan memprosesnya satu per satu saat tugas selesai daripada memprosesnya dalam urutan dimulai.
Contoh berikut menggunakan kueri untuk membuat kumpulan tugas. Setiap tugas mengunduh konten situs web tertentu. Dalam setiap perulangan sementara, panggilan yang ditunggu untuk WhenAny
mengembalikan tugas dalam kumpulan tugas yang menyelesaikan unduhannya terlebih dahulu. Tugas tersebut dihapus dari koleksi dan diproses. Perulangan diulang hingga koleksi tidak berisi lebih banyak tugas.
Nota
Untuk menjalankan contoh, Anda harus memasang Visual Studio 2012 atau yang lebih baru dan .NET Framework 4.5 atau yang lebih baru di komputer Anda.
Mengunduh Contoh
Anda dapat mengunduh proyek Windows Presentation Foundation (WPF) lengkap dari Async Sample: Fine Tuning Your Application lalu ikuti langkah-langkah berikut.
Dekompresi file yang Anda unduh, lalu mulai Visual Studio.
Pada bilah menu, pilih File, Buka, Proyek/Solusi.
Dalam kotak dialog Buka Proyek , buka folder yang menyimpan kode sampel yang Anda dekompresi, lalu buka file solusi (.sln) untuk AsyncFineTuningVB.
Di Penjelajah Solusi, buka menu pintasan untuk proyek ProcessTasksAsTheyFinish , lalu pilih Atur sebagai Proyek StartUp.
Pilih kunci F5 untuk menjalankan proyek.
Pilih tombol Ctrl+F5 untuk menjalankan proyek tanpa men-debugnya.
Jalankan proyek beberapa kali untuk memverifikasi bahwa panjang yang diunduh tidak selalu muncul dalam urutan yang sama.
Jika Anda tidak ingin mengunduh proyek, Anda dapat meninjau file MainWindow.xaml.vb di akhir topik ini.
Membangun Contoh
Contoh ini menambahkan ke kode yang dikembangkan di Batalkan Tugas Asinkron Yang Tersisa setelah Satu Selesai (Visual Basic) dan menggunakan UI yang sama.
Untuk membuat contoh sendiri, langkah demi langkah, ikuti instruksi di bagian "Mengunduh Contoh", tetapi pilih CancelAfterOneTask sebagai Proyek StartUp. Tambahkan perubahan dalam topik ini ke metode AccessTheWebAsync
dalam proyek tersebut. Perubahan ditandai dengan tanda bintang.
Proyek CancelAfterOneTask sudah menyertakan kueri yang, saat dijalankan, membuat kumpulan tugas. Setiap panggilan ke ProcessURLAsync
dalam kode berikut mengembalikan Task<TResult> di mana TResult
adalah bilangan bulat.
Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
From url In urlList Select ProcessURLAsync(url, client, ct)
Untuk membuat perubahan berikut pada metode AccessTheWebAsync
di dalam file MainWindow.xaml.vb di proyek.
Jalankan kueri dengan menerapkan Enumerable.ToList alih-alih ToArray.
Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()
Tambahkan perulangan while yang melakukan langkah-langkah berikut untuk setiap tugas dalam kumpulan.
Menunggu panggilan ke
WhenAny
untuk mengidentifikasi tugas pertama yang selesai diunduh dalam koleksi.Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
Menghapus tugas tersebut dari koleksi.
downloadTasks.Remove(finishedTask)
Menunggu
finishedTask
, yang dikembalikan oleh panggilan keProcessURLAsync
. VariabelfinishedTask
adalah Task<TResult> di manaTReturn
adalah bilangan bulat. Tugas sudah selesai, tetapi Anda menunggunya untuk mengambil panjang situs web yang diunduh, seperti yang ditunjukkan contoh berikut.Dim length = Await finishedTask resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website: {0}" & vbCrLf, length)
Anda harus menjalankan proyek beberapa kali untuk memverifikasi bahwa panjang yang diunduh tidak selalu muncul dalam urutan yang sama.
Perhatian
Anda dapat menggunakan WhenAny
dalam perulangan, seperti yang dijelaskan dalam contoh, untuk menyelesaikan masalah yang melibatkan sejumlah kecil tugas. Namun, pendekatan lain lebih efisien jika Anda memiliki sejumlah besar tugas untuk diproses. Untuk informasi dan contoh selengkapnya, lihat Memproses Tugas saat selesai.
Contoh Lengkap
Kode berikut adalah teks lengkap file MainWindow.xaml.vb untuk contoh. Tanda bintang menandai elemen yang ditambahkan untuk contoh ini.
Perhatikan bahwa Anda harus menambahkan referensi untuk System.Net.Http.
Anda dapat mengunduh proyek dari Sampel Asinkron: Menyempurnakan Aplikasi Anda.
' Add an Imports directive and a reference for System.Net.Http.
Imports System.Net.Http
' Add the following Imports directive for System.Threading.
Imports System.Threading
Class MainWindow
' Declare a System.Threading.CancellationTokenSource.
Dim cts As CancellationTokenSource
Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)
' Instantiate the CancellationTokenSource.
cts = New CancellationTokenSource()
resultsTextBox.Clear()
Try
Await AccessTheWebAsync(cts.Token)
resultsTextBox.Text &= vbCrLf & "Downloads complete."
Catch ex As OperationCanceledException
resultsTextBox.Text &= vbCrLf & "Downloads canceled." & vbCrLf
Catch ex As Exception
resultsTextBox.Text &= vbCrLf & "Downloads failed." & vbCrLf
End Try
' Set the CancellationTokenSource to Nothing when the download is complete.
cts = Nothing
End Sub
' You can still include a Cancel button if you want to.
Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)
If cts IsNot Nothing Then
cts.Cancel()
End If
End Sub
' Provide a parameter for the CancellationToken.
' Change the return type to Task because the method has no return statement.
Async Function AccessTheWebAsync(ct As CancellationToken) As Task
Dim client As HttpClient = New HttpClient()
' Call SetUpURLList to make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
' ***Create a query that, when executed, returns a collection of tasks.
Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
From url In urlList Select ProcessURLAsync(url, client, ct)
' ***Use ToList to execute the query and start the download tasks.
Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()
' ***Add a loop to process the tasks one at a time until none remain.
While downloadTasks.Count > 0
' ***Identify the first task that completes.
Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
' ***Remove the selected task from the list so that you don't
' process it more than once.
downloadTasks.Remove(finishedTask)
' ***Await the first completed task and display the results.
Dim length = Await finishedTask
resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website: {0}" & vbCrLf, length)
End While
End Function
' Bundle the processing steps for a website into one async method.
Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer)
' GetAsync returns a Task(Of HttpResponseMessage).
Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)
' Retrieve the website contents from the HttpResponseMessage.
Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
Return urlContents.Length
End Function
' Add a method that creates a list of web addresses.
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/library/ff730837.aspx"
}
Return urls
End Function
End Class
' Sample output:
' Length of the download: 226093
' Length of the download: 412588
' Length of the download: 175490
' Length of the download: 204890
' Length of the download: 158855
' Length of the download: 145790
' Length of the download: 44908
' Downloads complete.