Vorgehensweise: Paralleles Erstellen mehrerer Webanforderungen mit Async und Await (C#)How to: Make Multiple Web Requests in Parallel by Using async and await (C#)

In einer asynchronen Methode werden Aufgaben gestartet, wenn sie erstellt werden.In an async method, tasks are started when they’re created. Der await-Operator wird auf die Aufgabe an dem Punkt in der Methode angewendet, an dem die Verarbeitung nicht fortgesetzt werden kann, bis die Aufgabe abgeschlossen ist.The await operator is applied to the task at the point in the method where processing can’t continue until the task finishes. Häufig wird eine Aufgabe erwartet, sobald sie erstellt wird, wie das folgende Beispiel zeigt.Often a task is awaited as soon as it’s created, as the following example shows.

var result = await someWebAccessMethodAsync(url);  

Sie können das Erstellen der Aufgabe vom Erwarten der Aufgabe jedoch trennen, wenn das Programm weitere Arbeit durchführen muss, die nicht vom Abschluss der Aufgabe abhängig ist.However, you can separate creating the task from awaiting the task if your program has other work to accomplish that doesn’t depend on the completion of the task.

// 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 und dem Erwarten einer Aufgabe können Sie andere Aufgaben starten.Between starting a task and awaiting it, you can start other tasks. Die weiteren Aufgaben werden implizit parallel ausgeführt, es werden jedoch keine weiteren Threads erstellt.The additional tasks implicitly run in parallel, but no additional threads are created.

Das folgende Programm startet drei asynchrone Webdownloads und erwartet diese dann in der Reihenfolge, in der sie aufgerufen wurden.The following program starts three asynchronous web downloads and then awaits them in the order in which they’re called. Beachten Sie, dass die Aufgaben beim Ausführen des Programms nicht immer in der Reihenfolge abgeschlossen werden, in der sie erstellt und erwartet werden.Notice, when you run the program, that the tasks don’t always finish in the order in which they’re created and awaited. Sie beginnen mit der Ausführung, wenn sie erstellt werden, und eine oder mehrere Aufgaben werden u. U. abgeschlossen, bevor die Methode die await-Ausdrucke erreicht.They start to run when they’re created, and one or more of the tasks might finish before the method reaches the await expressions.

Hinweis

Zum Fertigstellen dieses Projekts muss Visual Studio 2012 oder höher sowie .NET Framework 4.5 oder höher auf dem Computer installiert sein.To complete this project, you must have Visual Studio 2012 or higher and the .NET Framework 4.5 or higher installed on your computer.

Ein weiteren Beispiel, in dem mehrere Aufgaben zur gleichen Zeit gestartet werden, finden Sie unter Vorgehensweise: Erweitern der asynchronen exemplarischen Vorgehensweise mit Task.WhenAll (C#).For another example that starts multiple tasks at the same time, see How to: Extend the async Walkthrough by Using Task.WhenAll (C#).

Sie können den Code für dieses Beispiel auf der Seite für Codebeispiele für Entwickler herunterladen.You can download the code for this example from Developer Code Samples.

So richten Sie das Projekt einTo set up the project

  1. Führen Sie die folgenden Schritte aus, um eine WPF-Anwendung einzurichten.To set up a WPF application, complete the following steps. Ausführliche Anweisungen zu diesen Schritten finden Sie unter Exemplarische Vorgehensweise: Zugreifen auf das Web mit async und await (C#).You can find detailed instructions for these steps in Walkthrough: Accessing the Web by Using async and await (C#).

    • Erstellen Sie eine WPF-Anwendung, die ein Textfeld und eine Schaltfläche enthält.Create a WPF application that contains a text box and a button. Benennen Sie die Schaltfläche mit startButton und das Textfeld mit resultsTextBox.Name the button startButton, and name the text box resultsTextBox.

    • Fügen Sie einen Verweis für System.Net.Http hinzu.Add a reference for System.Net.Http.

    • Fügen Sie in der Datei „MainWindow.xaml.cs“ ein using-Verzeichnis für System.Net.Http ein.In the MainWindow.xaml.cs file, add a using directive for System.Net.Http.

So fügen Sie den Code hinzuTo add the code

  1. Doppelklicken Sie im Entwurfsfenster „MainWindow.xaml“ auf die Schaltfläche, um den startButton_Click-Ereignishandler in „MainWindow.xaml.cs“ zu erstellen.In the design window, MainWindow.xaml, double-click the button to create the startButton_Click event handler in MainWindow.xaml.cs.

  2. Kopieren Sie den folgenden Code, und fügen Sie ihn in den Text von startButton_Click in „MainWindow.xaml.cs“ ein.Copy the following code, and paste it into the body of startButton_Click in MainWindow.xaml.cs.

    resultsTextBox.Clear();  
    await CreateMultipleTasksAsync();  
    resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";  
    

    Der Code ruft die asynchrone Methode CreateMultipleTasksAsync auf, die die Anwendung steuert.The code calls an asynchronous method, CreateMultipleTasksAsync, which drives the application.

  3. Fügen Sie dem Projekt die folgenden Unterstützungsmethoden hinzu:Add the following support methods to the project:

    • ProcessURLAsync verwendet eine HttpClient-Methode, um die Inhalte einer Website als Bytearray herunterzuladen.ProcessURLAsync uses an HttpClient method to download the contents of a website as a byte array. Die Unterstützungsmethode ProcessURLAsync wird daraufhin angezeigt und gibt die Länge des Arrays zurück.The support method, ProcessURLAsync then displays and returns the length of the array.

    • DisplayResults zeigt die Anzahl von Bytes im Bytearray für jede URL an.DisplayResults displays the number of bytes in the byte array for each URL. Diese Anzeige wird aufgerufen, wenn alle Aufgaben den Download abgeschlossen haben.This display shows when each task has finished downloading.

    Kopieren Sie die folgenden Methoden, und fügen Sie sie nach dem startButton_Click-Ereignishandler in „MainWindow.xaml.cs“ ein.Copy the following methods, and paste them after the startButton_Click event handler in MainWindow.xaml.cs.

    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. Definieren Sie schließlich die CreateMultipleTasksAsync-Methode, die die folgenden Schritte ausführt.Finally, define method CreateMultipleTasksAsync, which performs the following steps.

    • Die Methode deklariert ein HttpClient-Objekt, das Sie für den Zugriff auf die GetByteArrayAsync-Methode in ProcessURLAsync benötigen.The method declares an HttpClient object,which you need to access method GetByteArrayAsync in ProcessURLAsync.

    • Die Methode erstellt und startet drei Aufgaben vom Typ Task<TResult>, wobei TResult eine ganze Zahl ist.The method creates and starts three tasks of type Task<TResult>, where TResult is an integer. Beim Abschließen jeder Aufgabe zeigt DisplayResults die URL der Aufgabe sowie die Länge der heruntergeladenen Inhalte an.As each task finishes, DisplayResults displays the task's URL and the length of the downloaded contents. Da die Aufgaben asynchron ausgeführt werden, kann sich die Reihenfolge, in der die Ergebnisse angezeigt werden, von der Reihenfolge, in der sie deklariert wurden, unterscheiden.Because the tasks are running asynchronously, the order in which the results appear might differ from the order in which they were declared.

    • Die Methode erwartet den Abschluss jeder Aufgabe.The method awaits the completion of each task. Jeder await-Operator hält die Ausführung von CreateMultipleTasksAsync an, bis die erwartete Aufgabe abgeschlossen ist.Each await operator suspends execution of CreateMultipleTasksAsync until the awaited task is finished. Der Operator ruft außerdem den Rückgabewert des Aufrufs von ProcessURLAsync von jeder abgeschlossenen Aufgabe ab.The operator also retrieves the return value from the call to ProcessURLAsync from each completed task.

    • Wenn die Aufgaben abgeschlossen und die ganzzahligen Werte abgerufen wurden, werden die Längen der Websites von der Methode summiert, und das Ergebnis wird angezeigt.When the tasks have been completed and the integer values have been retrieved, the method sums the lengths of the websites and displays the result.

    Kopieren Sie die folgende Methode, und fügen Sie sie in Ihre Projektmappe ein.Copy the following method, and paste it into your solution.

    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("http://msdn.microsoft.com", client);  
        Task<int> download2 =   
            ProcessURLAsync("http://msdn.microsoft.com/library/hh156528(VS.110).aspx", client);  
        Task<int> download3 =   
            ProcessURLAsync("http://msdn.microsoft.com/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. Drücken Sie die Taste F5, um das Programm auszuführen, und klicken Sie dann auf die Schaltfläche Starten .Choose the F5 key to run the program, and then choose the Start button.

    Führen Sie das Programm mehrmals aus, um sicherzustellen, dass die drei Aufgaben nicht immer in derselben Reihenfolge abgeschlossen werden und dass die Reihenfolge, in der sie abgeschlossen werden, nicht notwendigerweise der Reihenfolge entspricht, in der sie erstellt und erwartet werden.Run the program several times to verify that the three tasks don’t always finish in the same order and that the order in which they finish isn't necessarily the order in which they’re created and awaited.

BeispielExample

Der folgende Code umfasst das vollständige Beispiel.The following code contains the full example.

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("http://msdn.microsoft.com", client);  
            Task<int> download2 =   
                ProcessURLAsync("http://msdn.microsoft.com/library/hh156528(VS.110).aspx", client);  
            Task<int> download3 =   
                ProcessURLAsync("http://msdn.microsoft.com/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 auchSee Also

Exemplarische Vorgehensweise: Zugreifen auf das Web mit „async“ und „await“ (C#)Walkthrough: Accessing the Web by Using async and await (C#)
Asynchronous Programming with async and await (C#) (Asynchrone Programmierung mit Async und Await (C#))Asynchronous Programming with async and await (C#)
Vorgehensweise: Erweitern der asynchronen exemplarischen Vorgehensweise mit Task.WhenAll (C#)How to: Extend the async Walkthrough by Using Task.WhenAll (C#)