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.
Sie können die Leistung der asynchronen Lösung in walkthrough verbessern: Zugreifen auf das Web mithilfe von Async und Await (Visual Basic) mithilfe der Task.WhenAll Methode. Diese Methode wartet auf mehrere asynchrone Vorgänge, die als Auflistung von Aufgaben dargestellt werden.
Möglicherweise haben Sie in der kurzen Einführung bemerkt, dass die Websites mit unterschiedlichen Geschwindigkeiten heruntergeladen werden. Manchmal ist eine der Websites sehr langsam, was alle verbleibenden Downloads verzögert. Wenn Sie die asynchronen Lösungen ausführen, die Sie in der exemplarischen Vorgehensweise erstellen, können Sie das Programm ganz einfach beenden, wenn Sie nicht warten möchten, aber eine bessere Option wäre, alle Downloads gleichzeitig zu starten und schnellere Downloads fortzusetzen, ohne auf das verzögerte Programm warten zu müssen.
Sie wenden die Task.WhenAll Methode auf eine Sammlung von Aufgaben an. Die Anwendung von WhenAll gibt eine einzelne Aufgabe zurück, die erst abgeschlossen ist, wenn jede Aufgabe in der Sammlung abgeschlossen ist. Die Aufgaben werden parallel ausgeführt, es werden jedoch keine zusätzlichen Threads erstellt. Die Aufgaben können in beliebiger Reihenfolge ausgeführt werden.
Von Bedeutung
Die folgenden Verfahren beschreiben Erweiterungen für die asynchronen Anwendungen, die in walkthrough entwickelt werden: Zugreifen auf das Web mithilfe von Async und Await (Visual Basic). Sie können die Anwendungen entwickeln, indem Sie entweder die exemplarische Vorgehensweise durcharbeiten oder das Beispiel aus dem .NET-Beispiel-Browser herunterladen. Der Beispielcode befindet sich im SerialAsyncExample-Projekt.
Zum Ausführen des Beispiels müssen Sie Visual Studio 2012 oder höher auf Ihrem Computer installiert haben.
So fügen Sie "Task.WhenAll" zu Ihrer GetURLContentsAsync-Lösung hinzu
Fügen Sie die
ProcessURLAsyncMethode zur ersten Anwendung hinzu, die in walkthrough entwickelt wird: Zugreifen auf das Web mithilfe von Async und Await (Visual Basic).Wenn Sie den Code aus Entwicklercodebeispielen heruntergeladen haben, öffnen Sie das Projekt "AsyncWalkthrough", und fügen Sie dann der MainWindow.xaml.vb Datei hinzu
ProcessURLAsync.Wenn Sie den Code mithilfe der exemplarischen Vorgehensweise entwickelt haben, fügen Sie
ProcessURLAsynczur Anwendung hinzu, die dieGetURLContentsAsyncMethode enthält. Die MainWindow.xaml.vb Datei für diese Anwendung ist das erste Beispiel im Abschnitt "Vollständige Codebeispiele aus der exemplarischen Vorgehensweise".
Die
ProcessURLAsync-Methode konsolidiert die Aktionen im Text derFor Each-Schleife inSumPageSizesAsyncin der ersten exemplarischen Vorgehensweise. Die Methode lädt den Inhalt einer angegebenen Website asynchron als Bytearray herunter und zeigt dann die Länge des Bytearrays an und gibt sie zurück.Private Async Function ProcessURLAsync(url As String) As Task(Of Integer) Dim byteArray = Await GetURLContentsAsync(url) DisplayResults(url, byteArray) Return byteArray.Length End FunctionKommentieren Sie die Schleife
For EachinSumPageSizesAsyncaus, oder löschen Sie sie, wie der folgenden Code zeigt.'Dim total = 0 'For Each url In urlList ' Dim urlContents As Byte() = Await GetURLContentsAsync(url) ' ' The previous line abbreviates the following two assignment statements. ' ' GetURLContentsAsync returns a task. At completion, the task ' ' produces a byte array. ' 'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url) ' 'Dim urlContents As Byte() = Await getContentsTask ' DisplayResults(url, urlContents) ' ' Update the total. ' total += urlContents.Length 'NextErstellen Sie eine Sammlung von Aufgaben. Der folgende Code definiert eine Abfrage , die beim Ausführen durch die ToArray Methode eine Sammlung von Aufgaben erstellt, die den Inhalt jeder Website herunterladen. Die Aufgaben werden gestartet, wenn die Abfrage ausgewertet wird.
Fügen Sie den folgenden Code zur Methode
SumPageSizesAsyncnach der Deklaration vonurlList.' Create a query. Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) = From url In urlList Select ProcessURLAsync(url) ' Use ToArray to execute the query and start the download tasks. Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()Wenden Sie
Task.WhenAllauf die Auflistung von AufgabendownloadTasksan.Task.WhenAllgibt einen einzelnen Vorgang zurück, der beendet wird, wenn alle Vorgänge in der Auflistung von Vorgängen abgeschlossen wurden.Im folgenden Beispiel erwartet der
Await-Ausdruck den Abschluss der einzelnen Aufgabe, dieWhenAllzurückgibt. Der Ausdruck wird zu einem Array ganzzahliger Zahlen ausgewertet, wobei jede ganze Zahl die Länge einer heruntergeladenen Website ist. Fügen Sie den folgenden CodeSumPageSizesAsyncdirekt nach dem Code hinzu, den Sie im vorherigen Schritt hinzugefügt haben.' Await the completion of all the running tasks. Dim lengths As Integer() = Await Task.WhenAll(downloadTasks) '' The previous line is equivalent to the following two statements. 'Dim whenAllTask As Task(Of Integer()) = Task.WhenAll(downloadTasks) 'Dim lengths As Integer() = Await whenAllTaskVerwenden Sie schließlich die Sum Methode, um die Summe der Längen aller Websites zu berechnen. Fügen Sie die folgende Zeile zu
SumPageSizesAsync.Dim total = lengths.Sum()
So fügen Sie Task.WhenAll zur HttpClient.GetByteArrayAsync-Lösung hinzu
Fügen Sie die folgende Version
ProcessURLAsyncder zweiten Anwendung hinzu, die in walkthrough entwickelt wird: Zugreifen auf das Web mithilfe von Async und Await (Visual Basic).Wenn Sie den Code aus Den Entwicklercodebeispielen heruntergeladen haben, öffnen Sie das AsyncWalkthrough_HttpClient Projekt, und fügen Sie dann der MainWindow.xaml.vb Datei hinzu
ProcessURLAsync.Wenn Sie den Code durch Ausführen der exemplarischen Vorgehensweise entwickelt haben, fügen Sie
ProcessURLAsyncder Anwendung hinzu, die dieHttpClient.GetByteArrayAsyncMethode verwendet. Die MainWindow.xaml.vb Datei für diese Anwendung ist das zweite Beispiel im Abschnitt "Vollständige Codebeispiele aus der exemplarischen Vorgehensweise".
Die
ProcessURLAsync-Methode konsolidiert die Aktionen im Text derFor Each-Schleife inSumPageSizesAsyncin der ersten exemplarischen Vorgehensweise. Die Methode lädt den Inhalt einer angegebenen Website asynchron als Bytearray herunter und zeigt dann die Länge des Bytearrays an und gibt sie zurück.Der einzige Unterschied zur
ProcessURLAsyncMethode in der vorherigen Prozedur ist die Verwendung der HttpClient Instanz.clientPrivate Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer) Dim byteArray = Await client.GetByteArrayAsync(url) DisplayResults(url, byteArray) Return byteArray.Length End FunctionKommentieren Sie die Schleife
For EachinSumPageSizesAsyncaus, oder löschen Sie sie, wie der folgenden Code zeigt.'Dim total = 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) ' ' The following two lines can replace the previous assignment statement. ' 'Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url) ' 'Dim urlContents As Byte() = Await getContentsTask ' DisplayResults(url, urlContents) ' ' Update the total. ' total += urlContents.Length 'NextDefinieren Sie eine Abfrage , die beim Ausführen durch die ToArray Methode eine Sammlung von Aufgaben erstellt, die die Inhalte jeder Website herunterladen. Die Aufgaben werden gestartet, wenn die Abfrage ausgewertet wird.
Fügen Sie den folgenden Code zur Methode
SumPageSizesAsyncnach der Deklaration vonclientundurlList.' Create a query. Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) = From url In urlList Select ProcessURLAsync(url, client) ' Use ToArray to execute the query and start the download tasks. Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()Wenden Sie
Task.WhenAllauf die Auflistung von Aufgaben an,downloadTasks.Task.WhenAllgibt einen einzelnen Vorgang zurück, der beendet wird, wenn alle Vorgänge in der Auflistung von Vorgängen abgeschlossen wurden.Im folgenden Beispiel erwartet der
Await-Ausdruck den Abschluss der einzelnen Aufgabe, dieWhenAllzurückgibt. Wenn der Ausdruck abgeschlossen ist, wird derAwaitAusdruck zu einem Array ganzzahliger Zahlen ausgewertet, wobei jede ganze Zahl die Länge einer heruntergeladenen Website ist. Fügen Sie den folgenden CodeSumPageSizesAsyncdirekt nach dem Code hinzu, den Sie im vorherigen Schritt hinzugefügt haben.' Await the completion of all the running tasks. Dim lengths As Integer() = Await Task.WhenAll(downloadTasks) '' The previous line is equivalent to the following two statements. 'Dim whenAllTask As Task(Of Integer()) = Task.WhenAll(downloadTasks) 'Dim lengths As Integer() = Await whenAllTaskVerwenden Sie schließlich die Sum Methode, um die Summe der Längen aller Websites abzurufen. Fügen Sie die folgende Zeile zu
SumPageSizesAsync.Dim total = lengths.Sum()
So testen Sie die Task.WhenAll-Lösungen
Wählen Sie für eine der Beiden Lösungen die F5-TASTE aus, um das Programm auszuführen, und klicken Sie dann auf die Schaltfläche " Start ". Die Ausgabe sollte der von den asynchronen Lösungen in Anleitung: Zugriff auf das Web mit Async und Await (Visual Basic) ähneln. Beachten Sie jedoch, dass die Websites jedes Mal in einer anderen Reihenfolge angezeigt werden.
Beispiel 1
Der folgende Code zeigt die Erweiterungen für das Projekt, die die GetURLContentsAsync Methode zum Herunterladen von Inhalten aus dem Web verwendet.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
resultsTextBox.Clear()
' One-step async call.
Await SumPageSizesAsync()
'' Two-step async call.
'Dim sumTask As Task = SumPageSizesAsync()
'Await sumTask
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
End Sub
Private Async Function SumPageSizesAsync() As Task
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
' Create a query.
Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
From url In urlList Select ProcessURLAsync(url)
' Use ToArray to execute the query and start the download tasks.
Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()
' You can do other work here before awaiting.
' Await the completion of all the running tasks.
Dim lengths As Integer() = Await Task.WhenAll(downloadTasks)
'' The previous line is equivalent to the following two statements.
'Dim whenAllTask As Task(Of Integer()) = Task.WhenAll(downloadTasks)
'Dim lengths As Integer() = Await whenAllTask
Dim total = lengths.Sum()
'Dim total = 0
'For Each url In urlList
' Dim urlContents As Byte() = Await GetURLContentsAsync(url)
' ' The previous line abbreviates the following two assignment statements.
' ' GetURLContentsAsync returns a task. At completion, the task
' ' produces a byte array.
' 'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
' 'Dim urlContents As Byte() = Await getContentsTask
' DisplayResults(url, urlContents)
' ' Update the total.
' total += urlContents.Length
'NextNext
' Display the total count for all of the web addresses.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"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
' The actions from the foreach loop are moved to this async method.
Private Async Function ProcessURLAsync(url As String) As Task(Of Integer)
Dim byteArray = Await GetURLContentsAsync(url)
DisplayResults(url, byteArray)
Return byteArray.Length
End Function
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
' The downloaded resource ends up in the variable named content.
Dim content = New MemoryStream()
' Initialize an HttpWebRequest for the current URL.
Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)
' Send the request to the Internet resource and wait for
' the response.
Using response As WebResponse = Await webReq.GetResponseAsync()
' Get the data stream that is associated with the specified URL.
Using responseStream As Stream = response.GetResponseStream()
' Read the bytes in responseStream and copy them to content.
' CopyToAsync returns a Task, not a Task<T>.
Await responseStream.CopyToAsync(content)
End Using
End Using
' Return the result as a byte array.
Return content.ToArray()
End Function
Private Sub DisplayResults(url As String, content As Byte())
' 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.
Dim bytes = content.Length
' Strip off the "https://".
Dim displayURL = url.Replace("https://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class
Beispiel 2
Der folgende Code zeigt die Erweiterungen für das Projekt, die methoden HttpClient.GetByteArrayAsync zum Herunterladen von Inhalten aus dem Web verwendet.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
resultsTextBox.Clear()
'' One-step async call.
Await SumPageSizesAsync()
'' Two-step async call.
'Dim sumTask As Task = SumPageSizesAsync()
'Await sumTask
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
End Sub
Private Async Function SumPageSizesAsync() As Task
' Declare an HttpClient object and increase the buffer size. The
' default buffer size is 65,536.
Dim client As HttpClient =
New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
' Create a query.
Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
From url In urlList Select ProcessURLAsync(url, client)
' Use ToArray to execute the query and start the download tasks.
Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()
' You can do other work here before awaiting.
' Await the completion of all the running tasks.
Dim lengths As Integer() = Await Task.WhenAll(downloadTasks)
'' The previous line is equivalent to the following two statements.
'Dim whenAllTask As Task(Of Integer()) = Task.WhenAll(downloadTasks)
'Dim lengths As Integer() = Await whenAllTask
Dim total = lengths.Sum()
''<snippet7>
'Dim total = 0
'For Each url In urlList
' ' GetByteArrayAsync returns a task. At completion, the task
' ' produces a byte array.
' '<snippet31>
' Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
' '</snippet31>
' ' The following two lines can replace the previous assignment statement.
' 'Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
' 'Dim urlContents As Byte() = Await getContentsTask
' DisplayResults(url, urlContents)
' ' Update the total.
' total += urlContents.Length
'NextNext
' Display the total count for all of the web addresses.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://www.msdn.com",
"https://msdn.microsoft.com/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"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
Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer)
Dim byteArray = Await client.GetByteArrayAsync(url)
DisplayResults(url, byteArray)
Return byteArray.Length
End Function
Private Sub DisplayResults(url As String, content As Byte())
' 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.
Dim bytes = content.Length
' Strip off the "https://".
Dim displayURL = url.Replace("https://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class