Sdílet prostřednictvím


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

  1. 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 startButtona pojmenujte textové pole resultsTextBox.

    • Přidejte odkaz pro System.Net.Http.

    • Do souboru MainWindow.xaml.vb přidejte příkaz Imports pro System.Net.Http.

Přidání kódu

  1. 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.

  2. 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, CreateMultipleTasksAsynckterá řídí aplikaci.

  3. Do projektu přidejte následující metody podpory:

    • ProcessURLAsync používá metodu HttpClient ke stažení obsahu webu jako bajtového pole. Metoda podpory ProcessURLAsync 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
    
  4. Nakonec definujte metodu CreateMultipleTasksAsync, která provádí následující kroky.

    • Metoda deklaruje HttpClient objekt, který potřebujete pro přístup k metodě GetByteArrayAsync v ProcessURLAsync.

    • 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í z ProcessURLAsync 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
    
  5. 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

Viz také