Gewusst wie: Paralleles Erstellen mehrerer Webanforderungen (C# und Visual Basic)

In einer asynchrone Methode werden Aufgaben gestartet, wenn sie erstellt werden.Der Operator Rechnen Sie (Visual Basic) oder Sie erwarten (C#) wird der Aufgabe am Punkt in der Methode angewendet, in dem die Verarbeitung nicht fortfahren kann bis zum Beenden der Aufgabe.Häufig wird eine Aufgabe, sobald sie erstellt hat, wie im folgenden Beispiel gezeigt erwartet.

Dim result = Await someWebAccessMethodAsync(url)
var result = await someWebAccessMethodAsync(url);

Sie können jedoch das Erstellen der Aufgabe im Rechnen der Aufgabe trennen, wenn das Programm andere geplante Arbeit hat, die nicht vom Abschluss der Aufgabe abhängig ist.

' 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
// The following line creates and starts the task.
var myTask = someWebAccessMethodAsync(url);

// While the task is running, you can do other work that doesn't depend
// on the results of the task.
// . . . . .

// The application of await suspends the rest of this method until the task is complete.
var result = await myTask;

Zwischen dem Starten einer Aufgabe und dem Rechnen sie, können Sie andere Aufgaben starten.Die zusätzlichen Aufgaben werden implizit parallel ausgeführt, aber keine weiteren Threads werden erstellt.

Die folgenden drei asynchrone gestartet Internet-Downloads erwartet und diese anschließend in der Reihenfolge, in der sie aufgerufen werden.Beachten Sie, wenn Sie das Programm, das die Aufgaben nicht immer in der Reihenfolge beenden, in der sie erstellt und erwartet werden.Sie beginnen, um ausgeführt zu werden, wenn sie erstellt werden, und eine oder mehrere der Aufgaben erhalten werden, bevor die Methode die Erwartungsausdrücke erreicht.

Ein weiteres Beispiel, das mehrere Aufgaben gleichzeitig gestartet wurde, finden Sie unter Gewusst wie: Erweitern der exemplarischen Vorgehensweise mit Task.WhenAll (C# und Visual Basic).

Um dieses Projekt abzuschließen, müssen Sie Visual Studio 2012 verfügen, das auf dem Computer installiert ist.Weitere Informationen finden Sie auf der Microsoft-Website.

Sie können den Code für dieses Beispiel von Entwickler-Codebeispiele herunterladen.

So richten Sie das Projekt ein

  • Um eine WPF-Anwendung zu installieren, führen Sie die folgenden Schritte aus.Sie können ausführliche Anweisungen für diese Schritte in Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await (C# und Visual Basic) suchen.

    • Erstellen Sie eine WPF-Anwendung, die ein Textfeld und eine Schaltfläche enthält.Nennen Sie die Schaltfläche startButton, und benennen Sie das Textfeld resultsTextBox.

    • Fügen Sie einen Verweis für System.Net.Http hinzu.

    • In Fügen Sie in "MainWindow.xaml.vb" bzw Imports eine Anweisung oder using-Direktiven für System.Net.Http hinzu.

So fügen Sie den Code hinzu

  1. Im Entwurfsfenster doppelklicken MainWindow.xaml, auf die Schaltfläche, um den startButton_Click-Ereignishandler in "MainWindow.xaml.vb" oder zu erstellen.Während eine Alternative, die Schaltfläche auswählen, wählen Sie das Ereignishandler für die ausgewählten Elemente Symbol im Eigenschaften aus, und geben Sie dann startButton_ClickKlicken im Textfeld ein.

  2. Kopieren Sie den folgenden Code, und fügen Sie ihn in den Text von startButton_Click in "MainWindow.xaml.vb" oder ein.

    resultsTextBox.Clear()
    Await CreateMultipleTasksAsync()
    resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    
    resultsTextBox.Clear();
    await CreateMultipleTasksAsync();
    resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
    

    Der Code ruft eine asynchrone Methode, CreateMultipleTasksAsync an, die die Anwendung steuert.

  3. Fügen Sie die folgenden Unterstützungsmethoden hinzu:

    • ProcessURLAsync verwendet eine HttpClient-Methode, um den Inhalt einer Website als Bytearray herunterzuladen.Die Stützmethode, ProcessURLAsync wird an und gibt die Länge des Arrays zurück.

    • DisplayResults zeigt die Anzahl von Bytes im Bytearray für jede URL an.In dieser Anzeige, wenn jede Aufgabe das Herunterladen beendet wurde.

    Kopieren Sie die folgenden Methoden, und fügen Sie sie nach dem startButton_Click-Ereignishandler in "MainWindow.xaml.vb" oder ein.

    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 "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
    async Task<int> ProcessURLAsync(string url, HttpClient client)
    {
        var byteArray = await client.GetByteArrayAsync(url);
        DisplayResults(url, byteArray);
        return byteArray.Length;
    }
    
    
    private void DisplayResults(string url, byte[] content)
    {
        // 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.
        var bytes = content.Length;
        // Strip off the "http://".
        var displayURL = url.Replace("http://", "");
        resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
    }
    
  4. Schließlich definieren Sie CreateMultipleTasksAsync-Methode, die die folgenden Schritte ausführen.

    • Die Methode deklariert HttpClient ein Objekt, das Sie Zugriffsmethode GetByteArrayAsync in ProcessURLAsync erfordern.

    • Die Methode erstellt und startet drei Aufgaben des Typs Task<TResult>, in dem TResult eine ganze Zahl ist.Wie Ende jeder Aufgabe, DisplayResults die URL und die Länge der Aufgabe des Inhalts heruntergeladenen anzeigt.Da die Aufgaben asynchron ausgeführt werden, kann sich die Reihenfolge, in der die Ergebnisse angezeigt werden, sich von der Reihenfolge, in der sie deklariert wurden.

    • Die Methode erwartet den Abschluss jeder Aufgabe.Jeder Await oder await-Operator enthält Ausführung von CreateMultipleTasksAsync an, bis die erwartete Aufgabe beendet ist.Der Operator ruft auch den Rückgabewert vom Aufruf von ProcessURLAsync von jeder abgeschlossenen Aufgabe ab.

    • Wenn die Aufgaben abgeschlossen wurden und die ganzzahligen Werte abgerufen wurden, zählt die Methode die Längen von Websites und zeigt das Ergebnis an.

    Kopieren Sie die folgende Methode, und fügen Sie sie in die Projektmappe ein.

    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/en-us/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/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 Task CreateMultipleTasksAsync()
    {
        // Declare an HttpClient object, and increase the buffer size. The
        // default buffer size is 65,536.
        HttpClient client =
            new HttpClient() { MaxResponseContentBufferSize = 1000000 };
    
        // Create and start the tasks. As each task finishes, DisplayResults 
        // displays its length.
        Task<int> download1 = 
            ProcessURLAsync("https://msdn.microsoft.com", client);
        Task<int> download2 = 
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
        Task<int> download3 = 
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);
    
        // Await each task.
        int length1 = await download1;
        int length2 = await download2;
        int length3 = await download3;
    
        int total = length1 + length2 + length3;
    
        // Display the total count for the downloaded websites.
        resultsTextBox.Text +=
            string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
    }
    
  5. Wählen Sie die F5-TASTE, um das Programm auszuführen, und wählen Sie dann die Schaltfläche Start aus.

    Führen Sie das Programm mehrmals ausgeführt werden, zu überprüfen, dass die drei Aufgaben nicht immer in der gleichen Reihenfolge beenden und die Reihenfolge, in der sie beenden, nicht unbedingt ist die Reihenfolge, in der sie erstellt und erwartet werden.

Beispiel

Der folgende Code umfasst das vollständige Beispiel.

' 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/en-us/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/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 "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directive, and add a reference for System.Net.Http.
using System.Net.Http;


namespace AsyncExample_MultipleTasks
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            resultsTextBox.Clear();
            await CreateMultipleTasksAsync();
            resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
        }


        private async Task CreateMultipleTasksAsync()
        {
            // Declare an HttpClient object, and increase the buffer size. The
            // default buffer size is 65,536.
            HttpClient client =
                new HttpClient() { MaxResponseContentBufferSize = 1000000 };

            // Create and start the tasks. As each task finishes, DisplayResults 
            // displays its length.
            Task<int> download1 = 
                ProcessURLAsync("https://msdn.microsoft.com", client);
            Task<int> download2 = 
                ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
            Task<int> download3 = 
                ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);

            // Await each task.
            int length1 = await download1;
            int length2 = await download2;
            int length3 = await download3;

            int total = length1 + length2 + length3;

            // Display the total count for the downloaded websites.
            resultsTextBox.Text +=
                string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
        }


        async Task<int> ProcessURLAsync(string url, HttpClient client)
        {
            var byteArray = await client.GetByteArrayAsync(url);
            DisplayResults(url, byteArray);
            return byteArray.Length;
        }


        private void DisplayResults(string url, byte[] content)
        {
            // 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.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await (C# und Visual Basic)

Gewusst wie: Erweitern der exemplarischen Vorgehensweise mit Task.WhenAll (C# und Visual Basic)

Konzepte

Asynchrone Programmierung mit Async und Await (C# und Visual Basic)