Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Mithilfe von Task.WhenAny" können Sie mehrere Aufgaben gleichzeitig starten und sie einzeln verarbeiten, da sie abgeschlossen sind, anstatt sie in der Reihenfolge zu verarbeiten, in der sie gestartet werden.
Im folgenden Beispiel wird eine Abfrage verwendet, um eine Sammlung von Aufgaben zu erstellen. Jede Aufgabe lädt den Inhalt einer angegebenen Website herunter. In jeder Iteration einer While-Schleife gibt ein erwarteter Aufruf von WhenAny
die Aufgabe in der Auflistung von Aufgaben zurück, die ihren Download zuerst beendet. Diese Aufgabe wird aus der Auflistung entfernt und verarbeitet. Die Schleife wird wiederholt, bis die Auflistung keine weiteren Aufgaben enthält.
Hinweis
Zum Ausführen der Beispiele müssen Sie Visual Studio 2012 oder höher und .NET Framework 4.5 oder höher auf Ihrem Computer installiert haben.
Herunterladen des Beispiels
Sie können das vollständige Windows Presentation Foundation (WPF)-Projekt aus dem Async-Beispiel herunterladen: Optimieren Sie Ihre Anwendung , und führen Sie dann die folgenden Schritte aus.
Dekomprimieren Sie die heruntergeladene Datei, und starten Sie Dann Visual Studio.
Wählen Sie auf der Menüleiste "Datei", "Öffnen", "Projekt/Projektmappe" aus.
Öffnen Sie im Dialogfeld "Projekt öffnen" den Ordner mit dem Beispielcode, den Sie dekomprimiert haben, und öffnen Sie dann die Lösungsdatei (.sln) für AsyncFineTuningVB.
Öffnen Sie im Projektmappen-Explorer das Kontextmenü für das Projekt ProcessTasksAsTheyFinish und wählen dann Als Startprojekt festlegen aus.
Wählen Sie die F5-TASTE aus, um das Projekt auszuführen.
Wählen Sie die STRG+F5-Tasten aus, um das Projekt auszuführen, ohne es zu debuggen.
Führen Sie das Projekt mehrmals aus, um sicherzustellen, dass die heruntergeladenen Längen nicht immer in derselben Reihenfolge angezeigt werden.
Wenn Sie das Projekt nicht herunterladen möchten, können Sie die MainWindow.xaml.vb Datei am Ende dieses Themas überprüfen.
Erstellen des Beispiels
Dieses Beispiel ergänzt den Code, der in Cancel Remaining Async Tasks after One Is Complete (Visual Basic) entwickelt wurde, und verwendet die gleiche Benutzeroberfläche.
Um das Beispiel selbst zu erstellen, befolgen Sie schritt für Schritt die Anweisungen im Abschnitt "Herunterladen des Beispiels", wählen Sie aber CancelAfterOneTask als StartUp-Projekt aus. Fügen Sie die Änderungen in diesem Thema zur AccessTheWebAsync
-Methode in diesem Projekt hinzu. Die Änderungen werden mit Sternchen markiert.
Das Projekt CancelAfterOneTask enthält bereits eine Abfrage, die beim Ausführen eine Sammlung von Vorgängen erstellt. Jeder Aufruf von ProcessURLAsync
im nachfolgenden Code gibt ein Task<TResult> zurück, wobei TResult
eine ganze Zahl ist.
Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
From url In urlList Select ProcessURLAsync(url, client, ct)
Nehmen Sie in der datei MainWindow.xaml.vb des Projekts die folgenden Änderungen an der AccessTheWebAsync
Methode vor.
Führen Sie die Abfrage aus, indem Sie Enumerable.ToList anstelle von ToArray anwenden.
Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()
Fügen Sie eine While-Schleife hinzu, die die folgenden Schritte für jede Aufgabe in der Auflistung ausführt.
Erwartet einen Aufruf von
WhenAny
, um die erste Aufgabe in der Auflistung zu identifizieren, die ihren Download beendet.Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
Entfernt die entsprechende Aufgabe aus der Auflistung.
downloadTasks.Remove(finishedTask)
Erwartet
finishedTask
, das durch einen Aufruf vonProcessURLAsync
zurückgegeben wird. DiefinishedTask
Variable ist eine Task<TResult>, bei derTReturn
eine ganze Zahl ist. Die Aufgabe ist bereits abgeschlossen, aber Sie warten darauf, die Länge der heruntergeladenen Website abzurufen, wie im folgenden Beispiel gezeigt.Dim length = Await finishedTask resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website: {0}" & vbCrLf, length)
Sie sollten das Projekt mehrmals ausführen, um sicherzustellen, dass die heruntergeladenen Längen nicht immer in derselben Reihenfolge angezeigt werden.
Vorsicht
Sie können WhenAny
in einer Schleife verwenden, wie im Beispiel beschrieben, um Probleme zu lösen, die eine kleine Anzahl von Aufgaben umfassen. Andere Ansätze sind jedoch effizienter, wenn Sie über eine große Anzahl von Aufgaben verfügen, die verarbeitet werden sollen. Weitere Informationen und Beispiele finden Sie unter Processing Tasks as they complete (Verarbeitung von Aufgaben nach deren Abschluss).
Vollständiges Beispiel
Der folgende Code ist der vollständige Text der MainWindow.xaml.vb-Datei für das Beispiel. Sternchen markieren die Elemente, die für dieses Beispiel hinzugefügt wurden.
Beachten Sie, dass Sie einen Verweis für System.Net.Http hinzufügen müssen.
Sie können das Projekt aus dem Async-Beispiel herunterladen: Optimieren Sie Ihre Anwendung.
' 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.