Compartir a través de


Cancelar una tarea asincrónica o una lista de tareas (Visual Basic)

Puede configurar un botón que puede usar para cancelar una aplicación asincrónica si no desea esperar a que finalice. Si sigue los ejemplos de este tema, puede agregar un botón de cancelación a una aplicación que descargue el contenido de un sitio web o una lista de sitios web.

Los ejemplos usan la interfaz de usuario que Fine-Tuning Your Async Application (Visual Basic) describe.

Nota:

Para ejecutar los ejemplos, debe tener Visual Studio 2012 o versiones posteriores y .NET Framework 4.5 o posterior instalado en el equipo.

Cancelar una tarea

En el primer ejemplo se asocia el botón Cancelar con una sola tarea de descarga. Si elige el botón mientras la aplicación está descargando contenido, se cancela la descarga.

Descarga del ejemplo

Puede descargar el proyecto completo de Windows Presentation Foundation (WPF) de Async Sample: Fine Tuning Your Application y luego siga estos pasos.

  1. Descomprima el archivo que descargó e inicie Visual Studio.

  2. En la barra de menús, elija Archivo, Abrir, Proyecto o solución.

  3. En el cuadro de diálogo Abrir proyecto , abra la carpeta que contiene el código de ejemplo que descomprimió y, a continuación, abra el archivo de solución (.sln) para AsyncFineTuningVB.

  4. En el Explorador de soluciones, abra el menú contextual del proyecto CancelATask y elija Establecer como proyecto de inicio.

  5. Elija la tecla F5 para ejecutar el proyecto.

    Presione las teclas Ctrl+F5 para ejecutar el proyecto sin depurarlo.

Si no desea descargar el proyecto, puede revisar los archivos MainWindow.xaml.vb al final de este tema.

Creación del ejemplo

Los cambios siguientes agregan un botón Cancelar a una aplicación que descarga un sitio web. Si no desea descargar o compilar el ejemplo, puede revisar el producto final en la sección "Ejemplos completos" al final de este tema. Los asteriscos marcan los cambios en el código.

Para compilar el ejemplo, paso a paso, siga las instrucciones de la sección "Descargar el ejemplo", pero elija StarterCode como proyecto de inicio en lugar de CancelATask.

A continuación, agregue los siguientes cambios al archivo MainWindow.xaml.vb de ese proyecto.

  1. Declare una CancellationTokenSource variable, cts, que esté dentro del ámbito de todos los métodos que puedan acceder a ella.

    Class MainWindow
    
        ' ***Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
  2. Agregue el siguiente controlador de eventos para el botón Cancelar . El controlador de eventos usa el CancellationTokenSource.Cancel método para notificar cts cuándo el usuario solicita la cancelación.

    ' ***Add an event handler for the Cancel button.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)
    
        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub
    
  3. Realice los siguientes cambios en el controlador de eventos para el botón Iniciar , startButton_Click.

    • Cree una instancia de CancellationTokenSource, cts.

      ' ***Instantiate the CancellationTokenSource.
      cts = New CancellationTokenSource()
      
    • En la llamada a AccessTheWebAsync, que descarga el contenido de un sitio web especificado, envíe la CancellationTokenSource.Token propiedad de cts como argumento. La Token propiedad propaga el mensaje si se solicita la cancelación. Agregue un bloque catch que muestre un mensaje si el usuario decide cancelar la operación de descarga. En el código siguiente se muestran los cambios.

      Try
          ' ***Send a token to carry the message if cancellation is requested.
          Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token)
      
          resultsTextBox.Text &=
              vbCrLf & $"Length of the downloaded string: {contentLength}." & vbCrLf
      
          ' *** If cancellation is requested, an OperationCanceledException results.
      Catch ex As OperationCanceledException
          resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf
      
      Catch ex As Exception
          resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
      End Try
      
  4. En AccessTheWebAsync, use la sobrecarga HttpClient.GetAsync(String, CancellationToken) del método GetAsync en el tipo HttpClient para descargar el contenido de un sitio web. Pase ct, el CancellationToken parámetro de AccessTheWebAsync, como segundo argumento. El token lleva el mensaje si el usuario elige el botón Cancelar .

    En el código siguiente se muestran los cambios en AccessTheWebAsync.

    ' ***Provide a parameter for the CancellationToken.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task(Of Integer)
    
        Dim client As HttpClient = New HttpClient()
    
        resultsTextBox.Text &= vbCrLf & "Ready to download." & vbCrLf
    
        ' You might need to slow things down to have a chance to cancel.
        Await Task.Delay(250)
    
        ' GetAsync returns a Task(Of HttpResponseMessage).
        ' ***The ct argument carries the message if the Cancel button is chosen.
        Dim response As HttpResponseMessage = Await client.GetAsync("https://msdn.microsoft.com/library/dd470362.aspx", ct)
    
        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
    
        ' The result of the method is the length of the downloaded website.
        Return urlContents.Length
    End Function
    
  5. Si no cancela el programa, genera la siguiente salida:

    Ready to download.
    Length of the downloaded string: 158125.
    

    Si elige el botón Cancelar antes de que el programa termine de descargar el contenido, el programa genera la siguiente salida:

    Ready to download.
    Download canceled.
    

Cancelar una lista de tareas

Puede ampliar el ejemplo anterior para cancelar muchas tareas asociando la misma CancellationTokenSource instancia con cada tarea. Si elige el botón Cancelar , cancela todas las tareas que aún no se han completado.

Descarga del ejemplo

Puede descargar el proyecto completo de Windows Presentation Foundation (WPF) de Async Sample: Fine Tuning Your Application y luego siga estos pasos.

  1. Descomprima el archivo que descargó e inicie Visual Studio.

  2. En la barra de menús, elija Archivo, Abrir, Proyecto o solución.

  3. En el cuadro de diálogo Abrir proyecto , abra la carpeta que contiene el código de ejemplo que descomprimió y, a continuación, abra el archivo de solución (.sln) para AsyncFineTuningVB.

  4. En el Explorador de soluciones, abra el menú contextual del proyecto CancelAListOfTasks y, a continuación, elija Establecer como proyecto de inicio.

  5. Elija la tecla F5 para ejecutar el proyecto.

    Presione las teclas Ctrl+F5 para ejecutar el proyecto sin depurarlo.

Si no desea descargar el proyecto, puede revisar los archivos MainWindow.xaml.vb al final de este tema.

Creación del ejemplo

Para ampliar el ejemplo, paso a paso, siga las instrucciones de la sección "Descargar el ejemplo", pero elija CancelarATask como proyecto de inicio. Agregue los cambios siguientes a ese proyecto. Los asteriscos marcan los cambios en el programa.

  1. Agregue un método para crear una lista de direcciones web.

    ' ***Add a method that creates a list of web addresses.
    Private Function SetUpURLList() As List(Of String)
    
        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/library/hh290138.aspx",
                "https://msdn.microsoft.com/library/hh290140.aspx",
                "https://msdn.microsoft.com/library/dd470362.aspx",
                "https://msdn.microsoft.com/library/aa578028.aspx",
                "https://msdn.microsoft.com/library/ms404677.aspx",
                "https://msdn.microsoft.com/library/ff730837.aspx"
            }
        Return urls
    End Function
    
  2. Llame al método en AccessTheWebAsync.

    ' ***Call SetUpURLList to make a list of web addresses.
    Dim urlList As List(Of String) = SetUpURLList()
    
  3. Agregue el siguiente bucle en AccessTheWebAsync para procesar cada dirección web de la lista.

    ' ***Add a loop to process the list of web addresses.
    For Each url In urlList
        ' GetAsync returns a Task(Of HttpResponseMessage).
        ' Argument ct carries the message if the Cancel button is chosen.
        ' ***Note that the Cancel button can cancel all remaining downloads.
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)
    
        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
    
        resultsTextBox.Text &=
            vbCrLf & $"Length of the downloaded string: {urlContents.Length}." & vbCrLf
    Next
    
  4. Dado que AccessTheWebAsync muestra las longitudes, el método no necesita devolver nada. Quite la instrucción return y cambie el tipo de valor devuelto del método a Task en lugar de Task<TResult>.

    Async Function AccessTheWebAsync(ct As CancellationToken) As Task
    

    Llame al método desde startButton_Click mediante una instrucción en lugar de una expresión.

    Await AccessTheWebAsync(cts.Token)
    
  5. Si no cancela el programa, genera la siguiente salida:

    Length of the downloaded string: 35939.
    
    Length of the downloaded string: 237682.
    
    Length of the downloaded string: 128607.
    
    Length of the downloaded string: 158124.
    
    Length of the downloaded string: 204890.
    
    Length of the downloaded string: 175488.
    
    Length of the downloaded string: 145790.
    
    Downloads complete.
    

    Si elige el botón Cancelar antes de que se completen las descargas, la salida contiene las longitudes de las descargas que se completaron antes de la cancelación.

    Length of the downloaded string: 35939.
    
    Length of the downloaded string: 237682.
    
    Length of the downloaded string: 128607.
    
    Downloads canceled.
    

Ejemplos completos

Las secciones siguientes contienen el código de cada uno de los ejemplos anteriores. Observe que debe agregar una referencia para System.Net.Http.

Puede descargar los proyectos desde Async Sample: Ajuste de la aplicación.

Ejemplo de cancelación de una tarea

El código siguiente es el archivo completo MainWindow.xaml.vb para el ejemplo que cancela una sola tarea.

' Add an Imports directive and a reference for System.Net.Http.
Imports System.Net.Http

' Add the following Imports directive for System.Threading.
Imports System.Threading

Class MainWindow

    ' ***Declare a System.Threading.CancellationTokenSource.
    Dim cts As CancellationTokenSource

    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)
        ' ***Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try
            ' ***Send a token to carry the message if cancellation is requested.
            Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token)

            resultsTextBox.Text &=
                vbCrLf & $"Length of the downloaded string: {contentLength}." & vbCrLf

            ' *** If cancellation is requested, an OperationCanceledException results.
        Catch ex As OperationCanceledException
            resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
        End Try

        ' ***Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing
    End Sub

    ' ***Add an event handler for the Cancel button.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)

        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub

    ' ***Provide a parameter for the CancellationToken.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task(Of Integer)

        Dim client As HttpClient = New HttpClient()

        resultsTextBox.Text &=
            vbCrLf & "Ready to download." & vbCrLf

        ' You might need to slow things down to have a chance to cancel.
        Await Task.Delay(250)

        ' GetAsync returns a Task(Of HttpResponseMessage).
        ' ***The ct argument carries the message if the Cancel button is chosen.
        Dim response As HttpResponseMessage = Await client.GetAsync("https://msdn.microsoft.com/library/dd470362.aspx", ct)

        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

        ' The result of the method is the length of the downloaded website.
        Return urlContents.Length
    End Function
End Class

' Output for a successful download:

' Ready to download.

' Length of the downloaded string: 158125.

' Or, if you cancel:

' Ready to download.

' Download canceled.

Cancelar una lista de tareas de ejemplo

El código siguiente es el archivo completo MainWindow.xaml.vb para el ejemplo que cancela una lista de tareas.

' Add an Imports directive and a reference for System.Net.Http.
Imports System.Net.Http

' Add the following Imports directive for System.Threading.
Imports System.Threading

Class MainWindow

    ' Declare a System.Threading.CancellationTokenSource.
    Dim cts As CancellationTokenSource

    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)

        ' Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try
            ' ***AccessTheWebAsync returns a Task, not a Task(Of Integer).
            Await AccessTheWebAsync(cts.Token)
            '  ***Small change in the display lines.
            resultsTextBox.Text &= vbCrLf & "Downloads complete."

        Catch ex As OperationCanceledException
            resultsTextBox.Text &= vbCrLf & "Downloads canceled." & vbCrLf

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Downloads failed." & vbCrLf
        End Try

        ' Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing
    End Sub

    ' Add an event handler for the Cancel button.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)

        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub

    ' Provide a parameter for the CancellationToken.
    ' ***Change the return type to Task because the method has no return statement.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task

        Dim client As HttpClient = New HttpClient()

        ' ***Call SetUpURLList to make a list of web addresses.
        Dim urlList As List(Of String) = SetUpURLList()

        ' ***Add a loop to process the list of web addresses.
        For Each url In urlList
            ' GetAsync returns a Task(Of HttpResponseMessage).
            ' Argument ct carries the message if the Cancel button is chosen.
            ' ***Note that the Cancel button can cancel all remaining downloads.
            Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

            ' Retrieve the website contents from the HttpResponseMessage.
            Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

            resultsTextBox.Text &=
                vbCrLf & $"Length of the downloaded string: {urlContents.Length}." & vbCrLf
        Next
    End Function

    ' ***Add a method that creates a list of web addresses.
    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/library/hh290138.aspx",
                "https://msdn.microsoft.com/library/hh290140.aspx",
                "https://msdn.microsoft.com/library/dd470362.aspx",
                "https://msdn.microsoft.com/library/aa578028.aspx",
                "https://msdn.microsoft.com/library/ms404677.aspx",
                "https://msdn.microsoft.com/library/ff730837.aspx"
            }
        Return urls
    End Function

End Class

' Output if you do not choose to cancel:

' Length of the downloaded string: 35939.

' Length of the downloaded string: 237682.

' Length of the downloaded string: 128607.

' Length of the downloaded string: 158124.

' Length of the downloaded string: 204890.

' Length of the downloaded string: 175488.

' Length of the downloaded string: 145790.

' Downloads complete.

'  Sample output if you choose to cancel:

' Length of the downloaded string: 35939.

' Length of the downloaded string: 237682.

' Length of the downloaded string: 128607.

' Downloads canceled.

Consulte también