Postupy: Paralelní provádění více webových požadavků pomocí Async a Await (Visual Basic)
V asynchronní metodě se úlohy spustí při jejich vytvoření. Operátor Await se použije na úkol v okamžiku v metodě, kde zpracování nemůže pokračovat, dokud se úkol nedokončí. Úloha se často očekává, jakmile se vytvoří, jak ukazuje následující příklad.
Dim result = Await someWebAccessMethodAsync(url)
Vytvoření úkolu však můžete oddělit od čekání na úkol, pokud má program jinou práci, která nezávisí na dokončení úkolu.
' The following line creates and starts the task.
Dim myTask = someWebAccessMethodAsync(url)
' While the task is running, you can do other work that does not depend
' on the results of the task.
' . . . . .
' The application of Await suspends the rest of this method until the task is
' complete.
Dim result = Await myTask
Mezi zahájením úkolu a čekáním na něj můžete začít s dalšími úkoly. Další úlohy se implicitně spouští paralelně, ale nevytvořila se žádná další vlákna.
Následující program spustí tři asynchronní stahování webu a pak je čeká v pořadí, ve kterém jsou volány. Všimněte si, že když program spustíte, úkoly se vždy nedokončí v pořadí, v jakém jsou vytvořeny a očekávána. Začnou se spouštět při jejich vytvoření a jedna nebo více úloh se může dokončit před tím, než metoda dosáhne výrazů await.
Poznámka:
K dokončení tohoto projektu musíte mít na počítači nainstalovanou sadu Visual Studio 2012 nebo vyšší a rozhraní .NET Framework 4.5 nebo vyšší.
Další příklad, který spouští více úkolů najednou, naleznete v tématu Postupy: Rozšíření Async Návod pomocí Task.WhenAll (Visual Basic).
Kód pro tento příklad si můžete stáhnout z ukázek vývojářského kódu.
Vytvoření projektu
Pokud chcete nastavit aplikaci WPF, proveďte následující kroky. Podrobné pokyny pro tyto kroky najdete v návodu: Přístup k webu pomocí Async a Await (Visual Basic).
Vytvořte aplikaci WPF, která obsahuje textové pole a tlačítko. Pojmenujte tlačítko
startButton
a pojmenujte textové poleresultsTextBox
.Přidejte odkaz pro System.Net.Http.
Do souboru MainWindow.xaml.vb přidejte příkaz
Imports
proSystem.Net.Http
.
Přidání kódu
V okně návrhu MainWindow.xaml poklikáním na tlačítko vytvořte obslužnou rutinu
startButton_Click
události v MainWindow.xaml.vb.Zkopírujte následující kód a vložte ho
startButton_Click
do textu v MainWindow.xaml.vb.resultsTextBox.Clear() Await CreateMultipleTasksAsync() resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
Kód volá asynchronní metodu,
CreateMultipleTasksAsync
která řídí aplikaci.Do projektu přidejte následující metody podpory:
ProcessURLAsync
používá metodu HttpClient ke stažení obsahu webu jako bajtového pole. Metoda podporyProcessURLAsync
pak zobrazí a vrátí délku pole.DisplayResults
zobrazí počet bajtů v bajtovém poli pro každou adresu URL. Toto zobrazení se zobrazí po dokončení stahování jednotlivých úkolů.
Zkopírujte následující metody a vložte je za obslužnou rutinu
startButton_Click
události v MainWindow.xaml.vb.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
Nakonec definujte metodu
CreateMultipleTasksAsync
, která provádí následující kroky.Metoda deklaruje
HttpClient
objekt, který potřebujete pro přístup k metodě GetByteArrayAsync vProcessURLAsync
.Metoda vytvoří a spustí tři úkoly typu Task<TResult>, kde
TResult
je celé číslo. Po dokončeníDisplayResults
každého úkolu se zobrazí adresa URL úkolu a délka staženého obsahu. Vzhledem k tomu, že úlohy běží asynchronně, může se pořadí, ve kterém se výsledky zobrazí, lišit od pořadí, ve kterém byly deklarovány.Metoda očekává dokončení každého úkolu. Každý
Await
operátor pozastaví prováděníCreateMultipleTasksAsync
, dokud se nedokončí očekávaný úkol. Operátor také načte vrácenou hodnotu z volání zProcessURLAsync
každého dokončeného úkolu.Po dokončení úkolů a načtení celočíselné hodnoty metoda sečte délky webů a zobrazí výsledek.
Zkopírujte následující metodu a vložte ji do svého řešení.
Private Async Function CreateMultipleTasksAsync() 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} ' Create and start the tasks. As each task finishes, DisplayResults ' displays its length. Dim download1 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com", client) Dim download2 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client) Dim download3 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client) ' Await each task. Dim length1 As Integer = Await download1 Dim length2 As Integer = Await download2 Dim length3 As Integer = Await download3 Dim total As Integer = length1 + length2 + length3 ' Display the total count for all of the websites. resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "Total bytes returned: {0}" & vbCrLf, total) End Function
Zvolte klávesu F5, aby se program spustil, a pak zvolte tlačítko Start .
Spusťte program několikrát, abyste ověřili, že se tyto tři úkoly nedokončí vždy ve stejném pořadí a že pořadí, ve kterém se dokončí, nemusí nutně odpovídat pořadí, ve kterém jsou vytvořeny a očekávána.
Příklad
Následující kód obsahuje úplný příklad.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
resultsTextBox.Clear()
Await CreateMultipleTasksAsync()
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
End Sub
Private Async Function CreateMultipleTasksAsync() 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}
' Create and start the tasks. As each task finishes, DisplayResults
' displays its length.
Dim download1 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com", client)
Dim download2 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client)
Dim download3 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client)
' Await each task.
Dim length1 As Integer = Await download1
Dim length2 As Integer = Await download2
Dim length3 As Integer = Await download3
Dim total As Integer = length1 + length2 + length3
' Display the total count for all of the websites.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
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