Cómo: Hacer varias solicitudes web en paralelo (C# y Visual Basic)

En un método async, se inician las tareas cuando se crean.Se aplican al operador de Espera (Visual Basic) o de espera (C#) para la tarea en el punto del método donde no puede continuar el procesamiento hasta que los finals de la tarea.Una tarea se espera a menudo en cuanto haya creado, como se muestra en el ejemplo siguiente.

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

Sin embargo, puede separar facilitar la tarea de aguardar la tarea si el programa tiene otro trabajo a lograr que no depende de la finalización de la tarea.

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

Entre iniciar una tarea y aguardarla, puede iniciar otras tareas.Las tareas adicionales se ejecutan implícitamente en paralelo, pero no se crea ningún subproceso adicionales.

El inicio del siguiente programa tres descargas de web asincrónico y después se espera en el orden en el que se llama.Observe, si ejecuta el programa, que las tareas no finalizado siempre en el orden en que se crean y se aguarda.Empiezan a ejecutarse cuando se crean, y uno o más de las tareas termine antes de que el método cobertura expresiones de aguardar.

Para obtener otro ejemplo que inicie tareas simultáneamente, vea Cómo: Ampliar el tutorial usando Task.WhenAll (C# y Visual Basic).

Para completar este proyecto, debe tener Visual Studio 2012 instalado en el equipo.Para obtener más información, vea en el sitio web de Microsoft.

Puede descargar el código de este ejemplo de Ejemplos de código del desarrollador.

Para configurar el proyecto

  • Para configurar una aplicación WPF, complete los pasos siguientes.Puede encontrar las instrucciones detalladas para estos pasos en Walkthrough: Acceso a web usando Async y Await (C# y Visual Basic).

    • Cree una aplicación WPF que contiene un botón y un cuadro de texto.Llame al botón startButton, y llame al cuadro de texto resultsTextBox.

    • Agregue una referencia a System.Net.Http.

    • En MainWindow.xaml.vb o MainWindow.xaml.cs, agregue un fragmento de Imports o una directiva de using para System.Net.Http.

Para agregar código

  1. En la ventana de diseño, MainWindow.xaml, haga doble clic en el botón para crear el controlador de eventos startButton_Click en MainWindow.xaml.vb o MainWindow.xaml.cs.Como alternativa, seleccione el botón, seleccione el icono de Controladores de eventos para los elementos seleccionados en la ventana de Propiedades , y especifique en startButton_Click en el cuadro de texto de Haga clic en .

  2. Copie el código siguiente, y péguelo en el cuerpo de startButton_Click en MainWindow.xaml.vb o MainWindow.xaml.cs.

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

    El código llama a un método asincrónico, CreateMultipleTasksAsync, que controla la aplicación.

  3. Agregue los métodos admiten siguientes al proyecto:

    • ProcessURLAsync utiliza un método de HttpClient para descargar el contenido de un sitio Web como una matriz de bytes.El método compatible con, ProcessURLAsync después muestra y devuelve la longitud de la matriz.

    • DisplayResults muestra el número de bytes de la matriz de bytes para cada dirección URL.Esta presentación muestra cuando cada tarea ha terminado descargar.

    Copie los siguientes métodos, y péguelos después del controlador de eventos de startButton_Click en MainWindow.xaml.vb o 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. Finalmente, defina el método CreateMultipleTasksAsync, que realiza los pasos siguientes.

    • El método declara un objeto de HttpClient , que necesita el método de acceso GetByteArrayAsync en ProcessURLAsync.

    • El método crea e inicia tres tareas de Task<TResult>escriba, donde es un entero TResult .Como los finals de cada tarea, DisplayResults muestran la dirección URL y la longitud de la tarea del contenido descargado.Dado que las tareas se ejecutan de forma asincrónica, el orden en que los resultados podría diferir del orden en que se declararon.

    • El método espera la finalización de cada tarea.Cada operador de Await o de await suspende la ejecución de CreateMultipleTasksAsync hasta que finalice la tarea aguardada.El operador también recupera el valor devuelto de la llamada a ProcessURLAsync de cada tarea completa.

    • Cuando se han completado las tareas y se han recuperado los valores enteros, el método suma las longitudes de los sitios Web y muestra el resultado.

    Copie el siguiente método, y péguelo en la solución.

    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. Elija la tecla F5 para ejecutar el programa, y elija el botón de Iniciar .

    Ejecute el programa varias veces para comprobar que las tres tareas no finalizado siempre en el mismo orden y que el orden en que finalizado no es necesariamente el orden en que se crean y se aguarda.

Ejemplo

El código siguiente contiene el ejemplo completo.

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

Vea también

Tareas

Walkthrough: Acceso a web usando Async y Await (C# y Visual Basic)

Cómo: Ampliar el tutorial usando Task.WhenAll (C# y Visual Basic)

Conceptos

Programación asincrónica con Async y Await (C# y Visual Basic)