Cancelar tarefas assíncronas após um período (C# e Visual Basic)
Você pode cancelar uma operação assíncrona após um período de tempo usando o método CancellationTokenSource.CancelAfter se não quiser esperar a conclusão da operação. Este método agenda o cancelamento de todas as tarefas associadas que não foram concluídas dentro do período de tempo designado pela expressão CancelAfter.
Este exemplo adiciona o código que é desenvolvido no Cancelar uma tarefa assíncrona ou uma lista de tarefas (C# e Visual Basic) para baixar uma lista de sites e exibir o comprimento do conteúdo de cada um.
Dica
Para executar os exemplos, você deve ter o Visual Studio 2012, Visual Studio 2013, Visual Studio Express 2012 para Windows Desktop, Visual Studio Express 2013 para Windows, ou o .NET Framework 4.5 ou 4.5.1 instalado em seu computador.
Baixando o Exemplo
Você pode baixar projeto completo do Windows Presentation Foundation (WPF) de Exemplo de Async: Ajustando seu aplicativo.
Descompacte o arquivo que você baixou e inicie o Visual Studio.
Na barra de menu, escolha Arquivo, Abrir, Projeto/solução.
Na caixa de diálogo Abrir Projeto , abra a pasta que contém o código de exemplo que você descompactou, e abra o arquivo de solução (.sln) para AsyncFineTuningCS ou AsyncFineTuningVB.
Em Gerenciador de Soluções, abra o menu de atalho para o projeto CancelAfterTime e escolha Definir como Projeto de Inicialização.
Escolha a tecla F5 para executar o projeto.
Escolha as chaves Ctrl+F5 para executar o projeto sem depurá-las.
Execute o programa várias vezes para verificar se a saída pode mostrar saída para todos os sites, os sites, ou alguns sites.
Se você não quiser baixar o projeto, você pode examinar os arquivos de MainWindow.xaml.vb e de MainWindow.xaml.cs no final deste tópico.
Compilando o Exemplo
O exemplo neste tópico é adicionado ao projeto que é desenvolvido em Cancelar uma tarefa assíncrona ou uma lista de tarefas (C# e Visual Basic) para cancelar uma lista de tarefas. O exemplo usa a mesma interface do usuário, embora o botão Cancelar não seja usado explicitamente.
Para criar o exemplo você mesmo, passo a passo, siga as instruções na seção "Baixando o exemplo", mas selecione CancelAListOfTasks como Projeto de inicialização. Adicione as alterações neste tópico para o projeto.
Para especificar um horário máximo antes que as tarefas sejam marcadas como canceladas, adicione uma chamada a CancelAfter para startButton_Click, como mostra o exemplo a seguir. A adição é marcada com asteriscos.
Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)
' Instantiate the CancellationTokenSource.
cts = New CancellationTokenSource()
resultsTextBox.Clear()
Try
' ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You
' can adjust the time.)
cts.CancelAfter(2500)
Await AccessTheWebAsync(cts.Token)
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
private async void startButton_Click(object sender, RoutedEventArgs e)
{
// Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();
resultsTextBox.Clear();
try
{
// ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You
// can adjust the time.)
cts.CancelAfter(2500);
await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += "\r\nDownloads succeeded.\r\n";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.\r\n";
}
cts = null;
}
Execute o programa várias vezes para verificar se a saída pode mostrar saída para todos os sites, os sites, ou alguns sites. A saída a seguir é um modelo.
Length of the downloaded string: 35990.
Length of the downloaded string: 407399.
Length of the downloaded string: 226091.
Downloads canceled.
Exemplo completo
O código a seguir é o texto completo de MainWindow.xaml.vb ou de MainWindow.xaml.cs do exemplo. Os asteriscos marcam os elementos que foram adicionados para esse exemplo.
Observe que você deve adicionar uma referência para System.Net.Http.
Você pode baixar o projeto de Exemplo de Async: Ajustando seu aplicativo.
' 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
' ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You
' can adjust the time.)
cts.CancelAfter(2500)
Await AccessTheWebAsync(cts.Token)
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
' You can still include a Cancel button if you want to.
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()
' Process each element in 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 &=
String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, urlContents.Length)
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/en-us/library/hh290138.aspx",
"https://msdn.microsoft.com/en-us/library/hh290140.aspx",
"https://msdn.microsoft.com/en-us/library/dd470362.aspx",
"https://msdn.microsoft.com/en-us/library/aa578028.aspx",
"https://msdn.microsoft.com/en-us/library/ms404677.aspx",
"https://msdn.microsoft.com/en-us/library/ff730837.aspx"
}
Return urls
End Function
End Class
' Sample output:
' Length of the downloaded string: 35990.
' Length of the downloaded string: 407399.
' Length of the downloaded string: 226091.
' Downloads canceled.
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 a using directive and a reference for System.Net.Http.
using System.Net.Http;
// Add the following using directive.
using System.Threading;
namespace CancelAfterTime
{
public partial class MainWindow : Window
{
// Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;
public MainWindow()
{
InitializeComponent();
}
private async void startButton_Click(object sender, RoutedEventArgs e)
{
// Instantiate the CancellationTokenSource.
cts = new CancellationTokenSource();
resultsTextBox.Clear();
try
{
// ***Set up the CancellationTokenSource to cancel after 2.5 seconds. (You
// can adjust the time.)
cts.CancelAfter(2500);
await AccessTheWebAsync(cts.Token);
resultsTextBox.Text += "\r\nDownloads succeeded.\r\n";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.\r\n";
}
cts = null;
}
// You can still include a Cancel button if you want to.
private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}
async Task AccessTheWebAsync(CancellationToken ct)
{
// Declare an HttpClient object.
HttpClient client = new HttpClient();
// Make a list of web addresses.
List<string> urlList = SetUpURLList();
foreach (var url in urlList)
{
// GetAsync returns a Task<HttpResponseMessage>.
// Argument ct carries the message if the Cancel button is chosen.
// Note that the Cancel button cancels all remaining downloads.
HttpResponseMessage response = await client.GetAsync(url, ct);
// Retrieve the website contents from the HttpResponseMessage.
byte[] urlContents = await response.Content.ReadAsByteArrayAsync();
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", urlContents.Length);
}
}
private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com/en-us/library/hh290136.aspx",
"https://msdn.microsoft.com/en-us/library/ee256749.aspx",
"https://msdn.microsoft.com/en-us/library/ms404677.aspx",
"https://msdn.microsoft.com/en-us/library/ff730837.aspx"
};
return urls;
}
}
// Sample Output:
// Length of the downloaded string: 35990.
// Length of the downloaded string: 407399.
// Length of the downloaded string: 226091.
// Downloads canceled.
}
Consulte também
Tarefas
Instruções passo a passo: acessando a Web e usando Async e Await (C# e Visual Basic)
Conceitos
Programação assíncrona com Async e Await (C# e Visual Basic)
Cancelar uma tarefa assíncrona ou uma lista de tarefas (C# e Visual Basic)
Ajustando seu aplicativo Async (C# e Visual Basic)