Biri Tamamlandıktan Sonra Kalan Zaman Uyumsuz Görevleri İptal Etme (Visual Basic)
yöntemini ile birlikte kullanarak Task.WhenAny , bir CancellationTokengörev tamamlandığında kalan tüm görevleri iptal edebilirsiniz. yöntemi, WhenAny
bir görev koleksiyonu olan bir bağımsız değişken alır. yöntemi tüm görevleri başlatır ve tek bir görev döndürür. Koleksiyondaki herhangi bir görev tamamlandığında tek görev tamamlanır.
Bu örnekte, bir iptal belirtecinin görev koleksiyonundan tamamlanıp kalan görevleri iptal etmek üzere ilk görevi tutmak için birlikte WhenAny
nasıl kullanılacağı gösterilmektedir. Her görev bir web sitesinin içeriğini indirir. Örnek, tamamlanmak üzere ilk indirmenin içeriğinin uzunluğunu görüntüler ve diğer indirmeleri iptal eder.
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'de CancelAfterOneTask projesinin kısayol menüsünü açın ve ardından StartUp 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.
Önce farklı indirmelerin tamamlandığını doğrulamak için programı 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 konudaki örnek, bir görev listesini iptal etmek için Zaman Uyumsuz Görevi İptal Et veya Görev Listesi'nde geliştirilen projeye eklenir. İptal düğmesi açıkça kullanılmasa da örnek 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 CancelAListOfTasks'i seçin. Bu konudaki değişiklikleri bu projeye ekleyin.
CancelAListOfTasks projesinin MainWindow.xaml.vb dosyasında, her web sitesi için işleme adımlarını döngüden AccessTheWebAsync
aşağıdaki zaman uyumsuz yönteme taşıyarak geçişi başlatın.
' ***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
bu AccessTheWebAsync
örnekte, bir dizi görev oluşturup başlatmak için bir sorgu ToArray , yöntemi ve WhenAny
yöntemi kullanılır. dizisine uygulaması WhenAny
, beklendiğinde görev dizisinde tamamlanmaya ulaşmak için ilk görevi değerlendiren tek bir görev döndürür.
içinde AccessTheWebAsync
aşağıdaki değişiklikleri yapın. Yıldız işaretleri, kod dosyasındaki değişiklikleri işaretler.
Döngüye açıklama ekleyin veya döngünün silinmesini sağlayın.
Yürütülürken genel görevlerden oluşan bir koleksiyon oluşturan bir sorgu oluşturun. çağrısının
ProcessURLAsync
her biri bir Task<TResult> whereTResult
değerini tamsayı olarak döndürür.' ***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)
Sorguyu yürütmek ve görevleri başlatmak için çağrısı
ToArray
yapın. Sonraki adımda yöntemininWhenAny
uygulanması sorguyu yürütür ve kullanmadanToArray
görevleri başlatır, ancak diğer yöntemler çalışmayabilir. En güvenli yöntem, sorgunun açıkça yürütülmesini zorlamaktır.' ***Use ToArray to execute the query and start the download tasks. Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()
Görev koleksiyonunda çağrısı
WhenAny
yapın.WhenAny
veyaTask(Of Task(Of Integer))
Task<Task<int>>
döndürür. Başka bir ifadeyle,WhenAny
tekTask(Of Integer)
bir görevi veyaTask<int>
ne zaman beklediğini değerlendiren bir görev döndürür. Bu tek görev koleksiyonda bitirecek ilk görevdir. İlk tamamlanan görev öğesinefinishedTask
atanır. türü,TResult
Task<TResult> değerininfinishedTask
dönüş türüProcessURLAsync
olduğundan tamsayıdır.' ***Call WhenAny and then await the result. The task that finishes ' first is assigned to finishedTask. Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
Bu örnekte yalnızca ilk olarak biten görevle ilgileniyorsunuz. Bu nedenle, kalan görevleri iptal etmek için kullanın CancellationTokenSource.Cancel .
' ***Cancel the rest of the downloads. You just want the first one. cts.Cancel()
Son olarak, indirilen içeriğin uzunluğunu almayı bekleyin
finishedTask
.Dim length = Await finishedTask resultsTextBox.Text &= vbCrLf & $"Length of the downloaded website: {length}" & vbCrLf
Önce farklı indirmelerin tamamlandığını doğrulamak için programı birkaç kez çalıştırın.
Tam Örnek
Aşağıdaki kod, örneğin tam MainWindow.xaml.vb veya MainWindow.xaml.cs dosyasıdır. 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 & "Download complete."
Catch ex As OperationCanceledException
resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf
Catch ex As Exception
resultsTextBox.Text &= vbCrLf & "Download 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()
'' Comment out or delete the loop.
''For Each url In urlList
'' ' GetAsync returns a Task(Of HttpResponseMessage).
'' ' Argument ct carries the message if the Cancel button is chosen.
'' ' Note that the Cancel button can cancel all remaining downloads.
'' Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)
'' ' Retrieve the website contents from the HttpResponseMessage.
'' Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
'' resultsTextBox.Text &=
'' vbCrLf & $"Length of the downloaded string: {urlContents.Length}." & vbCrLf
''Next
' ***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 ToArray to execute the query and start the download tasks.
Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()
' ***Call WhenAny and then await the result. The task that finishes
' first is assigned to finishedTask.
Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
' ***Cancel the rest of the downloads. You just want the first one.
cts.Cancel()
' ***Await the first completed task and display the results
' Run the program several times to demonstrate that different
' websites can finish first.
Dim length = Await finishedTask
resultsTextBox.Text &= vbCrLf & $"Length of the downloaded website: {length}" & vbCrLf
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 downloaded website: 158856
' Download complete.