Compartilhar via


Cancelar uma tarefa assíncrona ou uma lista de tarefas (Visual Basic)

Você pode configurar um botão que pode ser usado para cancelar um aplicativo assíncrono se não desejar aguardar sua conclusão. Seguindo os exemplos neste tópico, você pode adicionar um botão de cancelamento a um aplicativo que baixa o conteúdo de um site ou uma lista de sites.

Os exemplos usam a interface do usuário que Ajuste fino de seu aplicativo assíncrono (C#) descreve.

Observação

Para executar os exemplos, você precisa ter o Visual Studio 2012 ou uma versão mais recente e o .NET Framework 4.5 ou posterior instalados em seu computador.

Cancelar uma tarefa

O primeiro exemplo associa o botão Cancelar a uma única tarefa de download. Se você escolher o botão enquanto o aplicativo está baixando conteúdo, o download será cancelado.

Baixando o Exemplo

Você pode baixar o projeto completo do WPF (Windows Presentation Foundation) em Exemplo assíncrono: ajuste fino de seu aplicativo e, em seguida, seguir estas etapas.

  1. Descompacte o arquivo baixado e, em seguida, inicie o Visual Studio.

  2. Na barra de menus, escolha Arquivo, Abrir, Projeto/Solução.

  3. Na caixa de diálogo Abrir Projeto, abra a pasta em que está o código de exemplo que você descompactou e, em seguida, abra o arquivo de solução (.sln) de AsyncFineTuningVB.

  4. No Gerenciador de Soluções, abra o menu de atalho do projeto CancelATask e, em seguida, escolha Definir como Projeto de Inicialização.

  5. Escolha a tecla F5 para executar o projeto.

    Escolha as teclas CTRL+F5 para executar o projeto sem depurá-lo.

Se não quiser baixar o projeto, você poderá examinar o arquivo MainWindow.xaml.vb no final deste tópico.

Compilando o Exemplo

As alterações a seguir adicionam um botão Cancelar a um aplicativo que baixa um site. Se não desejar baixar ou compilar o exemplo, você poderá examinar o produto final na seção "Exemplos completos" no final deste tópico. Os asteriscos marcam as alterações no código.

Para compilar o exemplo você mesmo, passo a passo, siga as instruções na seção “Baixando o exemplo”, mas escolha StarterCode como o Projeto de Inicialização em vez de CancelATask.

Em seguida, adicione as seguintes alterações ao arquivo MainWindow.xaml.cs desse projeto.

  1. Declare uma variável CancellationTokenSource, cts, que está no escopo para todos os métodos a acessarem.

    Class MainWindow
    
        ' ***Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
  2. Adicione o seguinte manipulador de eventos para o botão Cancelar. O manipulador de eventos usa o método CancellationTokenSource.Cancel para notificar cts quando o usuário solicita o cancelamento.

    ' ***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. Faça as seguintes alterações no manipulador de eventos para o botão Iniciar, startButton_Click.

    • Crie a instância de CancellationTokenSource, cts.

      ' ***Instantiate the CancellationTokenSource.
      cts = New CancellationTokenSource()
      
    • Na chamada para AccessTheWebAsync, que baixa o conteúdo de um site especificado, envie a propriedade CancellationTokenSource.Token de cts como um argumento. A propriedade Token propaga a mensagem se o cancelamento é solicitado. Adicione um bloco catch que exibe uma mensagem se o usuário optar por cancelar a operação de download. O código a seguir mostra as alterações.

      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. No AccessTheWebAsync, use a sobrecarga HttpClient.GetAsync(String, CancellationToken) do método GetAsync no tipo HttpClient para baixar o conteúdo de um site. Passe ct, o parâmetro CancellationToken de AccessTheWebAsync, como o segundo argumento. O token executa a mensagem se o usuário escolhe o botão Cancelar.

    O código a seguir mostra as alterações em 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. Se você não cancelar o programa, ele produzirá a saída a seguir:

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

    Se você escolher o botão Cancelar antes de o programa terminar de baixar o conteúdo, o programa produzirá a saída a seguir:

    Ready to download.
    Download canceled.
    

Cancelar uma lista de tarefas

Você pode estender o exemplo anterior para cancelar muitas tarefas associando a mesma instância CancellationTokenSource a cada tarefa. Se você escolher o botão Cancelar, cancela todas as tarefas que ainda não estão concluídas.

Baixando o Exemplo

Você pode baixar o projeto completo do WPF (Windows Presentation Foundation) em Exemplo assíncrono: ajuste fino de seu aplicativo e, em seguida, seguir estas etapas.

  1. Descompacte o arquivo baixado e, em seguida, inicie o Visual Studio.

  2. Na barra de menus, escolha Arquivo, Abrir, Projeto/Solução.

  3. Na caixa de diálogo Abrir Projeto, abra a pasta em que está o código de exemplo que você descompactou e, em seguida, abra o arquivo de solução (.sln) de AsyncFineTuningVB.

  4. No Gerenciador de Soluções, abra o menu de atalho do projeto CancelAListOfTasks e, em seguida, escolha Definir como Projeto de Inicialização.

  5. Escolha a tecla F5 para executar o projeto.

    Escolha as teclas CTRL+F5 para executar o projeto sem depurá-lo.

Se não quiser baixar o projeto, você poderá examinar o arquivo MainWindow.xaml.vb no final deste tópico.

Compilando o Exemplo

Para estender o exemplo você mesmo, passo a passo, siga as instruções na seção "Baixando o exemplo", mas escolha CancelATask como o Projeto de Inicialização. Adicione as seguintes alterações ao projeto. Os asteriscos marcam as alterações no programa.

  1. Adicione um método para criar uma lista de endereços 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. Chame o método em AccessTheWebAsync.

    ' ***Call SetUpURLList to make a list of web addresses.
    Dim urlList As List(Of String) = SetUpURLList()
    
  3. Adicione o seguinte loop em AccessTheWebAsync para processar cada endereço web na 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. Como AccessTheWebAsync exibe os comprimentos, o método não precisa retornar nada. Remova a instrução de retorno e altere o tipo de retorno do método para Task em vez de Task<TResult>.

    Async Function AccessTheWebAsync(ct As CancellationToken) As Task
    

    Chame o método de startButton_Click usando uma instrução em vez de uma expressão.

    Await AccessTheWebAsync(cts.Token)
    
  5. Se você não cancelar o programa, ele produzirá a saída a seguir:

    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.
    

    Se você escolher o botão Cancelar antes de os downloads serem concluídos, a saída conterá os tamanhos dos downloads que foram concluídos antes do cancelamento.

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

Exemplos completos

As seções a seguir contêm o código para cada um dos exemplos anteriores. Observe que você deve adicionar uma referência para System.Net.Http.

Você pode baixar os projetos de Exemplo assíncrono: ajuste fino de seu aplicativo.

Exemplo de cancelar uma tarefa

O código a seguir é o arquivo MainWindow.xaml.cs completo do exemplo que cancela uma única tarefa.

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

Exemplo de cancelar uma lista de tarefas

O código a seguir é o arquivo MainWindow.xaml.cs completo do exemplo que cancela uma lista de tarefas.

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

Confira também