(0) exportieren Drucken
Alle erweitern
Dieser Artikel wurde manuell übersetzt. Bewegen Sie den Mauszeiger über die Sätze im Artikel, um den Originaltext anzuzeigen. Weitere Informationen
Übersetzung
Original

Gewusst wie: Paralleles Erstellen mehrerer Webanforderungen mit Async and Await (C# und Visual Basic)

In einer asynchronen Methode werden Aufgaben gestartet, wenn sie erstellt werden. Der Await-Operator (Visual Basic) bzw. await-Operator (C#) wird auf die Aufgabe an dem Punkt in der Methode angewendet, an dem die Verarbeitung nicht fortgesetzt werden kann, bis die Aufgabe abgeschlossen ist. Häufig wird eine Aufgabe erwartet, sobald sie erstellt wird, wie das folgende Beispiel zeigt.

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.

// 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. Die weiteren Aufgaben werden implizit parallel ausgeführt, es werden jedoch keine weiteren Threads erstellt.

Das folgende Programm startet drei asynchrone Webdownloads und erwartet diese dann in der Reihenfolge, in der sie aufgerufen wurden. Beachten Sie, dass die Aufgaben beim Ausführen des Programms nicht immer in der Reihenfolge abgeschlossen werden, in der sie erstellt und erwartet werden. 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.

HinweisHinweis

Um dieses Projekt abzuschließen, muss Visual Studio 2012, Visual Studio 2013, Visual Studio Express 2012 für Windows Desktop Visual Studio Express 2013 für Windows oder .NET Framework 4.5 bzw. 4.5.1 auf dem Computer installiert sein.

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

Sie können den Code für dieses Beispiel auf der Seite für Codebeispiele für Entwickler herunterladen.

So richten Sie das Projekt ein

  • Führen Sie die folgenden Schritte aus, um eine WPF-Anwendung einzurichten. Ausführliche Anweisungen für diese Schritte finden Sie unter Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await (C# und Visual Basic).

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

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

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

So fügen Sie den Code hinzu

  1. Doppelklicken Sie im Entwurfsfenster "MainWindow.xaml" auf die Schaltfläche, um den startButton_Click-Ereignishandler in "MainWindow.xaml.vb" bzw. "MainWindow.xaml.cs" zu erstellen. Wählen Sie alternativ die Schaltfläche aus, wählen Sie anschließend das Symbol Ereignishandler für die ausgewählten Elemente im Fenster Eigenschaften aus, und geben Sie im Textfeld Klicken die Zeichenfolge startButton_Click ein.

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

    
    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.

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

    • ProcessURLAsync verwendet eine HttpClient-Methode, um die Inhalte einer Website als Bytearray herunterzuladen. Die Unterstützungsmethode ProcessURLAsync wird daraufhin angezeigt und gibt die Länge des Arrays zurück.

    • DisplayResults zeigt die Anzahl von Bytes im Bytearray für jede URL an. Diese Anzeige wird aufgerufen, wenn alle Aufgaben den Download abgeschlossen haben.

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

    
    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.

    • Die Methode deklariert ein HttpClient-Objekt, das Sie für den Zugriff auf die GetByteArrayAsync-Methode in ProcessURLAsync benötigen.

    • Die Methode erstellt und startet drei Aufgaben vom Typ Task<TResult>, wobei TResult eine ganze Zahl ist. Beim Abschließen jeder Aufgabe zeigt DisplayResults die URL der Aufgabe sowie die Länge der heruntergeladenen Inhalte an. 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.

    • Die Methode erwartet den Abschluss jeder Aufgabe. Jeder Await- bzw. await-Operator hält die Ausführung von CreateMultipleTasksAsync an, bis die erwartete Aufgabe abgeschlossen ist. Der Operator ruft außerdem den Rückgabewert des Aufrufs von ProcessURLAsync von jeder abgeschlossenen Aufgabe ab.

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

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

    
    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/en-us/library/hh156528(VS.110).aspx", client);
        Task<int> download3 = 
            ProcessURLAsync("http://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 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.

Der folgende Code umfasst das vollständige Beispiel.


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/en-us/library/hh156528(VS.110).aspx", client);
            Task<int> download3 = 
                ProcessURLAsync("http://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);
        }
    }
}


Community-Beiträge

HINZUFÜGEN
Anzeigen:
© 2014 Microsoft