Практическое руководство. Параллельное выполнение нескольких веб-запросов (C# и Visual Basic)

В методе async, запускаются задачи при их создании.Оператор подождите (Visual Basic) или подождите (C#) применяется к задаче в точке в методе, где обработка не может продолжаться до тех пор, пока задача.Часто задача подождана после того как он был создан, как показано в следующем примере.

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

Однако можно разделить создать задачу из ожидание задачи если программа имеет другую работу, выполняемую, который не зависит от завершения задачи.

' 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;

Между задачей и начать ожидать его можно начинать другие задачи.Дополнительные задачи неявно выполняются параллельно, но отсутствуют дополнительные потоки не создаются.

Следующие запуске программы 3 загрузки через интернет асинхронного а затем ожидает их в порядке, в котором они были вызваны.Уведомления при запуске программы, которая всегда завершения задачи не в том порядке, в котором они создаются и подожданы.Они запускаются для запуска, когда они создаются и одну или несколько задач могут выполнить, прежде чем метод достигает выражения ожидания.

Полный пример, запускает несколько задач одновременно, см. в разделе Практическое руководство. Расширение пошагового руководства с использованием метода Task.WhenAll (C# и Visual Basic).

Для выполнения заданий данного проекта, необходимо иметь Visual Studio 2012 установлено на компьютере.Дополнительные сведения см. на веб-сайте Microsoft.

Можно загрузить код для этого примера Образцы кода для разработчиков.

Настройка проекта

Добавление кода

  1. В окне конструктора, файл MainWindow.xaml дважды нажмите кнопку, чтобы создать обработчик событий startButton_Click в MainWindow.xaml.cs или MainWindow.xaml.vb.В качестве альтернативы выберите кнопку, выберите значок *** Обработчики событий для выбранных элементов *** в окне Свойства, а затем введите startButton_Click в текстовое поле Щелчок.

  2. Скопируйте следующий код и вставьте его в тело сообщения startButton_Click в MainWindow.xaml.cs или MainWindow.xaml.vb.

    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";
    

    Код вызывает асинхронный метод, CreateMultipleTasksAsync, который управляет приложением.

  3. Добавьте в проект следующие методы поддержки:

    • ProcessURLAsync используется метод HttpClient чтобы загрузить содержимое веб-узел в виде массива байтов.Метод, ProcessURLAsync затем отображает и возвращает длину массива.

    • DisplayResults указывает число байтов в массиве байтов для каждого URL-адрес.Экрана, показывающий время завершения каждой задачи загрузить.

    Скопируйте следующие методы и вставьте их после обработчика событий в startButton_Click или MainWindow.xaml.vb MainWindow.xaml.cs.

    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. Наконец, укажите метод CreateMultipleTasksAsync, который выполняет следующие шаги.

    • Метод объявляется объект HttpClient, которому требуется метод доступа GetByteArrayAsync в ProcessURLAsync.

    • Метод создает и запускает 3 задачи типа Task<TResult>, где TResult целое число.По мере приближения завершения задача DisplayResults указывает URL-адрес и длину задачи загруженных содержимого.Поскольку задачи выполняются асинхронно, порядок, в котором отображаются результаты могут отличаться от порядка, в котором они были объявлены.

    • Метод ожидает завершения каждой задачи.Каждый оператор Await или await приостанавливает выполнение CreateMultipleTasksAsync до тех пор, пока подожданная задача не будет завершена.Оператор также получает возвращаемое значение вызова метода ProcessURLAsync из каждой завершенной задачи.

    • Если задачи выполнены и целочисленные значения были получены метод суммирует длину веб-сайтов и отображает результат.

    Скопируйте следующий метод и вставьте его в решение.

    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. Выберите ключ F5, чтобы запустить программу, а затем нажмите кнопку Запуск.

    Запустите программу несколько раз, чтобы убедиться, что не всегда 3 задачи завершатся в том же порядке и что порядок, в котором они завершатся не обязательно порядка, в котором они были созданы и подожданы.

Пример

Следующий код содержит полный пример.

' 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);
        }
    }
}

См. также

Задачи

Пошаговое руководство. Получение доступа к Интернету с помощью модификатора Async и оператора Await (C# и Visual Basic)

Практическое руководство. Расширение пошагового руководства с использованием метода Task.WhenAll (C# и Visual Basic)

Основные понятия

Асинхронное программирование с использованием ключевых слов Async и Await (C# и Visual Basic)