在一段时间后取消异步任务(C# 和 Visual Basic)
如果您不希望等待操作完成,则可在一段时间后使用 CancellationTokenSource.CancelAfter 方法取消异步操作。 此方法安排取消在 CancelAfter 表达式指定的时间段内无法完成的所有关联任务。
此示例添加到 取消一个异步任务或一组任务(C# 和 Visual Basic) 中开发的代码,以下载网站列表和显示每个网站的内容的长度。
备注
若要运行此示例,需在计算机上安装 Visual Studio 2012、Visual Studio 2013、Visual Studio Express 2012 for Windows Desktop(Visual Studio Express 2012 for Windows Desktop)、Visual Studio Express 2013 for Windows 或 .NET Framework 4.5 或 4.5.1。
下载示例
您可以从 Async Sample: Fine Tuning Your Application(异步示例:微调应用程序)下载完整的 Windows Presentation Foundation (WPF) 项目,然后按照这些步骤操作。
解压下载的文件,然后启动 Visual Studio。
在菜单栏上,依次选择**“文件”、“打开”和“项目/解决方案”**。
在“打开项目”对话框中,打开包含您解压缩的示例代码的文件夹,然后打开 AsyncFineTuningCS 或 AsyncFineTuningVB 的解决方案 (.sln) 文件。
在“解决方案资源管理器”中,打开“CancelAfterTime”项目的快捷菜单,然后选择“设置为启动项目”。
选择 F5 键运行项目。
选择 Ctrl+F5 键运行项目,但不对其进行调试。
多次运行程序以验证输出可以显示所有网站、无网站和部分网站的输出。
如果您不希望下载该项目,可以在本主题结尾查看 MainWindow.xaml.vb 和 MainWindow.xaml.cs 文件。
生成示例
本主题中的示例将添加到 取消一个异步任务或一组任务(C# 和 Visual Basic) 中开发的项目以取消任务列表。 该示例使用相同的 UI,不过,没有显式使用“取消”按钮。
要自己生成示例,请按照“下载示例”部分的说明一步一步操作,但请选择“CancelAListOfTasks”作为“启动项目”。 添加本主题中的更改到该项目。
要在任务被标记为已取消之前指定最大时间,请向 startButton_Click 添加对 CancelAfter 的调用,如下面的示例所示。 添加标记为星号。
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;
}
多次运行程序以验证输出可以显示所有网站、无网站和部分网站的输出。 下面的输出是一个示例。
Length of the downloaded string: 35990.
Length of the downloaded string: 407399.
Length of the downloaded string: 226091.
Downloads canceled.
完整的示例
下面的代码是该示例的 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件的完整文本。 星号标记出此示例中添加的元素。
请注意,您必须为 System.Net.Http 添加引用。
您可以从 Async 示例:优化应用程序中下载项目。
' 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.
}
请参见
任务
演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)
概念
使用 Async 和 Await 的异步编程(C# 和 Visual Basic)
取消一个异步任务或一组任务(C# 和 Visual Basic)