Partilhar via


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

Você pode configurar um botão que pode usar para cancelar um aplicativo assíncrono se não quiser esperar que ele termine. 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 Fine-Tuning Your Async Application (Visual Basic) descreve.

Nota

Para executar os exemplos, você deve ter o Visual Studio 2012 ou mais recente e o .NET Framework 4.5 ou mais recente instalado no 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 é cancelado.

Download do exemplo

Você pode baixar o projeto completo do Windows Presentation Foundation (WPF) de Async Sample: Fine Tuning Your Application e siga estas etapas.

  1. Descompacte o arquivo que você baixou 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 que contém o código de exemplo que você descompactou e, em seguida, abra o arquivo de solução (.sln) para AsyncFineTuningVB.

  4. No Gerenciador de Soluções, abra o menu de atalho para o projeto CancelATask e 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ê pode revisar os arquivos MainWindow.xaml.vb no final deste tópico.

Construindo o exemplo

As alterações a seguir adicionam um botão Cancelar a um aplicativo que baixa um site. Se não quiser baixar ou criar o exemplo, você pode revisar o produto final na seção "Exemplos completos" no final deste tópico. Asteriscos marcam as alterações no código.

Para construir 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.vb desse projeto.

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

    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 CancellationTokenSource.Cancel método para notificar cts quando o usuário solicita 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.

    • Instancie o CancellationTokenSource, cts.

      ' ***Instantiate the CancellationTokenSource.
      cts = New CancellationTokenSource()
      
    • Na chamada para AccessTheWebAsync, que baixa o conteúdo de um site especificado, envie a CancellationTokenSource.Token propriedade de cts como um argumento. A Token propriedade propaga a mensagem se o cancelamento for solicitado. Adicione um bloco catch que exiba 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. Em AccessTheWebAsync, use a HttpClient.GetAsync(String, CancellationToken) sobrecarga do GetAsync método no HttpClient tipo para baixar o conteúdo de um site. Passe ct, o CancellationToken parâmetro de AccessTheWebAsync, como o segundo argumento. O token carrega a mensagem se o usuário escolher o botão Cancelar .

    O código a seguir mostra as alterações no 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 seguinte saída:

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

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

    Ready to download.
    Download canceled.
    

Cancelar uma lista de tarefas

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

Download do exemplo

Você pode baixar o projeto completo do Windows Presentation Foundation (WPF) de Async Sample: Fine Tuning Your Application e siga estas etapas.

  1. Descompacte o arquivo que você baixou 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 que contém o código de exemplo que você descompactou e, em seguida, abra o arquivo de solução (.sln) para AsyncFineTuningVB.

  4. No Gerenciador de Soluções, abra o menu de atalho para o projeto CancelAListOfTasks e 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ê pode revisar os arquivos MainWindow.xaml.vb no final deste tópico.

Construindo 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 a esse projeto. Asteriscos marcam as mudanças no programa.

  1. Adicione um método para criar uma lista de endereços da 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 loop a seguir para AccessTheWebAsync processar cada endereço da 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 return 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 usando startButton_Click uma instrução em vez de uma expressão.

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

    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 que os downloads sejam concluídos, a saída conterá os comprimentos dos downloads 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 Async Sample: Fine Tuning Your Application.

Cancelar um exemplo de tarefa

O código a seguir é o arquivo de MainWindow.xaml.vb completo para o 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.

Cancelar um exemplo de lista de tarefas

O código a seguir é o arquivo de MainWindow.xaml.vb completo para o 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.

Consulte também