Birden çok zaman uyumsuz görevi başlatma ve tamamlandıkları gibi işleme (Visual Basic)
kullanarak Task.WhenAny, birden çok görevi aynı anda başlatabilir ve tamamlandıkları sırada işlemek yerine tek tek işleyebilirsiniz.
Aşağıdaki örnek, bir görev koleksiyonu oluşturmak için bir sorgu kullanır. Her görev, belirtilen bir web sitesinin içeriğini indirir. Bir while döngüsünün her yinelemesinde, beklenen çağrısı WhenAny
, önce indirme işlemini tamamlayan görev koleksiyonundaki görevi döndürür. Bu görev koleksiyondan kaldırılır ve işlenir. Döngü, koleksiyon başka görev içermeyene kadar yineler.
Not
Örnekleri çalıştırmak için bilgisayarınızda Visual Studio 2012 veya üzeri ve .NET Framework 4.5 veya daha yeni bir sürümü yüklü olmalıdır.
Örneği İndirme
Windows Presentation Foundation (WPF) projesinin tamamını Async Sample: Fine Tuning Your Application adresinden indirebilir ve ardından aşağıdaki adımları izleyebilirsiniz.
İndirdiğiniz dosyanın sıkıştırmasını açın ve Visual Studio'yu başlatın.
Menü çubuğunda Dosya, Aç, Proje/Çözüm'e tıklayın.
Projeyi Aç iletişim kutusunda, sıkıştırmasını kaldırdığınız örnek kodun bulunduğu klasörü açın ve ardından AsyncFineTuningVB için çözüm (.sln) dosyasını açın.
Çözüm Gezgini'da ProcessTasksAsTheyFinish projesinin kısayol menüsünü açın ve ardından Başlangıç Projesi Olarak Ayarla'yı seçin.
Projeyi çalıştırmak için F5 anahtarını seçin.
Projeyi hata ayıklamadan çalıştırmak için Ctrl+F5 tuşlarını seçin.
İndirilen uzunlukların her zaman aynı sırada görünmediğini doğrulamak için projeyi birkaç kez çalıştırın.
Projeyi indirmek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.vb dosyasını gözden geçirebilirsiniz.
Örneği Oluşturma
Bu örnek, Bir Tamamlandıktan Sonra Kalan Zaman Uyumsuz Görevleri İptal Et (Visual Basic) içinde geliştirilen koda ekler ve aynı kullanıcı arabirimini kullanır.
Örneği kendiniz oluşturmak için, adım adım "Örneği İndirme" bölümündeki yönergeleri izleyin, ancak StartUp Projesi olarak CancelAfterOneTask'i seçin. Bu konudaki değişiklikleri bu projedeki yöntemine AccessTheWebAsync
ekleyin. Değişiklikler yıldız işaretiyle işaretlenir.
CancelAfterOneTask projesi zaten yürütülürken bir görev koleksiyonu oluşturan bir sorgu içerir. Aşağıdaki koddaki her çağrısı ProcessURLAsync
bir Task<TResult> where TResult
değerinin tamsayı olduğunu döndürür.
Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
From url In urlList Select ProcessURLAsync(url, client, ct)
Projenin MainWindow.xaml.vb dosyasında yönteminde aşağıdaki değişiklikleri AccessTheWebAsync
yapın.
yerine uygulayarak Enumerable.ToList sorguyu yürütebilirsiniz ToArray.
Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()
Koleksiyondaki her görev için aşağıdaki adımları gerçekleştiren bir while döngüsü ekleyin.
Koleksiyondaki indirme işlemini tamamlayacak ilk görevi tanımlamak için bir çağrı
WhenAny
bekler.Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
Bu görevi koleksiyondan kaldırır.
downloadTasks.Remove(finishedTask)
awaits
finishedTask
, çağrısıProcessURLAsync
tarafından döndürülür.finishedTask
değişkeni, Task<TResult> bir tamsayı olan bir yerdirTReturn
. Görev zaten tamamlandı, ancak aşağıdaki örnekte gösterildiği gibi indirilen web sitesinin uzunluğunu almayı bekliyorsunuz.Dim length = Await finishedTask resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website: {0}" & vbCrLf, length)
İndirilen uzunlukların her zaman aynı sırada görünmediğini doğrulamak için projeyi birkaç kez çalıştırmanız gerekir.
Dikkat
Az sayıda görev içeren sorunları çözmek için örnekte açıklandığı gibi bir döngüde kullanabilirsiniz WhenAny
. Ancak, işlenmek üzere çok sayıda göreviniz varsa diğer yaklaşımlar daha verimlidir. Daha fazla bilgi ve örnek için bkz . Görevleri tamamlandıklarında işleme.
Tam Örnek
Aşağıdaki kod, örnek için MainWindow.xaml.vb dosyasının tam metnidir. Yıldız işaretleri, bu örnek için eklenen öğeleri işaretler.
için System.Net.Httpbir başvuru eklemeniz gerektiğine dikkat edin.
Projeyi Zaman Uyumsuz Örnek: Uygulamanızda İnce Ayarlama'dan indirebilirsiniz.
' 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.