Compartir a través de


Cómo: Realizar varias solicitudes web en paralelo mediante Async y Await (Visual Basic)

En un método asincrónico, las tareas se inician cuando se crean. El operador Await se aplica a la tarea en el punto del método donde el procesamiento no puede continuar hasta que finalice la tarea. A menudo se espera una tarea en cuanto se crea, como se muestra en el ejemplo siguiente.

Dim result = Await someWebAccessMethodAsync(url)

Sin embargo, puede separar la creación de la tarea de la espera por su finalización si el programa tiene otros trabajos que realizar y que no dependen de que se complete 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

Entre iniciar una tarea y esperarla, puede iniciar otras tareas. Las tareas adicionales se ejecutan implícitamente en paralelo, pero no se crean subprocesos adicionales.

El siguiente programa inicia tres descargas web asincrónicas y después las espera en el orden en el que son llamadas. Tenga en cuenta que, al ejecutar el programa, las tareas no siempre finalizan en el orden de creación y espera. Empiezan a ejecutarse en el momento de crearse y una o más tareas podrían finalizar antes de que el método llegue a las expresiones await.

Nota:

Para completar este proyecto, debe tener Visual Studio 2012 o superior y .NET Framework 4.5 o posterior instalado en el equipo.

Para obtener otro ejemplo que inicia varias tareas al mismo tiempo, vea How to: Extend the Async Walkthrough by Using Task.WhenAll (Visual Basic).

Puede descargar el código de este ejemplo en Ejemplos de código para desarrolladores.

Para configurar el proyecto

  1. Para configurar una aplicación WPF, complete los pasos siguientes. Puede encontrar instrucciones detalladas para estos pasos en Tutorial: Acceso a la Web mediante Async y Await (Visual Basic) .

    • Cree una aplicación WPF que contenga un cuadro de texto y un botón. Asigne al botón startButtonel nombre y asigne al cuadro resultsTextBoxde texto el nombre .

    • Agregue una referencia para System.Net.Http.

    • En el archivo MainWindow.xaml.vb, agregue una instrucción Imports para System.Net.Http.

Para agregar el código

  1. En la ventana de diseño, MainWindow.xaml, haga doble clic en el botón para crear el startButton_Click controlador de eventos en MainWindow.xaml.vb.

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

    resultsTextBox.Clear()
    Await CreateMultipleTasksAsync()
    resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    

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

  3. Agregue los siguientes métodos de soporte técnico al proyecto:

    • ProcessURLAsync usa un HttpClient método para descargar el contenido de un sitio web como una matriz de bytes. A continuación, el método de soporte técnico ProcessURLAsync 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 pantalla muestra cuándo cada tarea ha terminado de descargarse.

    Copie los métodos siguientes y péguelos después del startButton_Click controlador de eventos en MainWindow.xaml.vb.

    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 "https://".
        Dim displayURL = url.Replace("https://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
  4. Por último, defina el método CreateMultipleTasksAsync, que realiza los pasos siguientes.

    • El método declara un HttpClient objeto , que debe tener acceso al método GetByteArrayAsync en ProcessURLAsync.

    • El método crea e inicia tres tareas de tipo Task<TResult>, donde TResult es un entero. A medida que finaliza cada tarea, DisplayResults muestra la dirección URL de la tarea y la longitud del contenido descargado. Dado que las tareas se ejecutan de forma asincrónica, el orden en el que aparecen los resultados puede diferir del orden en que se declararon.

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

    • 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 método siguiente 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/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/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
    
  5. Presione la tecla F5 para ejecutar el programa y elija el botón Inicio .

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

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/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/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 "https://".
        Dim displayURL = url.Replace("https://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
End Class

Consulte también