取消一个任务或一组任务(C# 和 Visual Basic)
可以设置可以使用取消异步应用程序的按钮,如果您不希望等待其结束。 按照本主题中的示例,可以添加取消按钮到下载一个网站目录或网站列表的应用程序。
示例使用 微调异步应用程序(C# 和 Visual Basic) 描述的 UI。
备注
若要运行此示例,需要 Visual Studio 2012 中,Visual Studio express 2012 中的 windows 桌面或在您的计算机上安装 .NET framework 4.5。
取消任务
第一个示例关联 取消 按钮与单个下载任务。 如果选择按钮,当应用程序下载内容时,下载被取消。
下载示例
可以下载完整的 windows 演示基础 (WPF) 项从 Async 示例:优化应用程序 然后按照这些步骤。
对要下载的文件,然后启动 Visual Studio 2012。
在菜单栏上,依次选择**“文件”、“打开”和“项目/解决方案”**。
在 打开项目 对话框中,打开包含示例代码。解压缩,然后打开 AsyncFineTuningCS 或 AsyncFineTuningVB 的解决方案的文件夹 (.sln) 文件。
在 解决方案资源管理器,打开 CancelATask 项目的快捷菜单,然后选择 设为启动项目。
选择 F5 键运行项目。
选择密钥 Ctrl+F5 运行项目,但不对其进行调试。
如果不希望下载该项目,可以查看 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件本主题末尾的。
生成示例
下面的更改添加一个 取消 按钮到下载网站的应用程序。 如果不希望下载或生成该示例,您可以查看在“完整示例”部分的最终产品本主题末尾的。 星号指出代码中的更改。
若要生成此示例,分步,后面部分的“下载示例的”命令,但是,选择 StarterCode 作为 启动项目 而不是 CancelATask。
然后添加到该项 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件进行以下更改。
声明 CancellationTokenSource 变量,cts,在任何方法的范围访问该元素
Class MainWindow ' ***Declare a System.Threading.CancellationTokenSource. Dim cts As CancellationTokenSource
public partial class MainWindow : Window { // ***Declare a System.Threading.CancellationTokenSource. CancellationTokenSource cts;
添加 取消 按钮的下列事件处理程序。 事件处理程序使用 CancellationTokenSource.Cancel 方法通知 cts,当用户请求取消。
' ***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
// ***Add an event handler for the Cancel button. private void cancelButton_Click(object sender, RoutedEventArgs e) { if (cts != null) { cts.Cancel(); } }
可以在事件处理程序的以下更改 启动 按钮的,startButton_Click。
实例化 CancellationTokenSource,cts。
' ***Instantiate the CancellationTokenSource. cts = New CancellationTokenSource()
// ***Instantiate the CancellationTokenSource. cts = new CancellationTokenSource();
在对 AccessTheWebAsync的调用,下载一个指定的网站的内容,请发送 ctsCancellationTokenSource.Token 属性作为参数。 如果取消请求,Token 属性传播消息。 将显示消息的 catch 块,如果用户选择取消下载操作。 下面的代码演示更改。
Try ' ***Send a token to carry the message if cancellation is requested. Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token) resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength) ' *** 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
try { // ***Send a token to carry the message if cancellation is requested. int contentLength = await AccessTheWebAsync(cts.Token); resultsTextBox.Text += String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength); } // *** If cancellation is requested, an OperationCanceledException results. catch (OperationCanceledException) { resultsTextBox.Text += "\r\nDownload canceled.\r\n"; } catch (Exception) { resultsTextBox.Text += "\r\nDownload failed.\r\n"; }
在 AccessTheWebAsync,请使用 GetAsync 方法的 HttpClient.GetAsync(String, CancellationToken) 超加载到 HttpClient 类型下载网站的内容。 通过 ct,AccessTheWebAsync的 CancellationToken 参数,作为第二个参数。 如果用户选择 取消 按钮,标记传播消息。
下面的代码演示在 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 &= String.Format(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/en-us/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
// ***Provide a parameter for the CancellationToken. async Task<int> AccessTheWebAsync(CancellationToken ct) { HttpClient client = new HttpClient(); resultsTextBox.Text += String.Format("\r\nReady to download.\r\n"); // You might need to slow things down to have a chance to cancel. await Task.Delay(250); // GetAsync returns a Task<HttpResponseMessage>. // ***The ct argument carries the message if the Cancel button is chosen. HttpResponseMessage response = await client.GetAsync("https://msdn.microsoft.com/en-us/library/dd470362.aspx", ct); // Retrieve the website contents from the HttpResponseMessage. byte[] urlContents = await response.Content.ReadAsByteArrayAsync(); // The result of the method is the length of the downloaded website. return urlContents.Length; }
如果不移除程序,它产生下面的输出。
Ready to download. Length of the downloaded string: 158125.
如果选择 取消 按钮,在过程完成下载该内容之前,程序将生成以下输出。
Ready to download. Download canceled.
取消任务列表
可以扩展前面的示例通过将同一 CancellationTokenSource 实例中移除许多任务与每个任务。 如果选择 取消 按钮,则取消完成的所有任务。
下载示例
可以下载完整的 windows 演示基础 (WPF) 项从 Async 示例:优化应用程序 然后按照这些步骤。
对要下载的文件,然后启动 Visual Studio 2012。
在菜单栏上,依次选择**“文件”、“打开”和“项目/解决方案”**。
在 打开项目 对话框中,打开包含示例代码。解压缩,然后打开 AsyncFineTuningCS 或 AsyncFineTuningVB 的解决方案的文件夹 (.sln) 文件。
在 解决方案资源管理器,打开 CancelAListOfTasks 项目的快捷菜单,然后选择 设为启动项目。
选择 F5 键运行项目。
选择密钥 Ctrl+F5 运行项目,但不对其进行调试。
如果不希望下载该项目,可以查看 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件本主题末尾的。
生成示例
若要扩展此示例,分步,后面部分的“下载示例的”命令,但是,选择 CancelATask 作为 启动项目。 添加对该项目进行以下更改。 星号指出在程序中的更改。
添加一个方法以生成 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/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
// ***Add a method that creates a list of web addresses. private List<string> SetUpURLList() { List<string> urls = new List<string> { "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; }
调用 AccessTheWebAsync的方法。
' ***Call SetUpURLList to make a list of web addresses. Dim urlList As List(Of String) = SetUpURLList()
// ***Call SetUpURLList to make a list of web addresses. List<string> urlList = SetUpURLList();
将 AccessTheWebAsync 的以下循环处理该列表中的每个 web 地址。
' ***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 &= String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, urlContents.Length) Next
// ***Add a loop to process the list of web addresses. 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 can cancel 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); }
由于 AccessTheWebAsync 显示长度,方法不需要返回任何内容。 移除返回语句,并更改方法的返回类型为 Task 而不是 Task<TResult>。
Async Function AccessTheWebAsync(ct As CancellationToken) As Task
async Task AccessTheWebAsync(CancellationToken ct)
调用从 startButton_Click 的方法使用语句而不是表达式。
Await AccessTheWebAsync(cts.Token)
await AccessTheWebAsync(cts.Token);
如果不移除程序,它产生下面的输出。
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.
如果选择 取消 按钮,在下载之前完成后,输出包含长度的下载该移除前完成列表中。
Length of the downloaded string: 35939. Length of the downloaded string: 237682. Length of the downloaded string: 128607. Downloads canceled.
完成示例
以下各节包含每个的代码示例。 通知您必须添加 System.Net.Http的引用。
可以下载项目 Async 示例:优化应用程序。
取消任务示例
下面的代码是移除单个任务的示例的完整 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件。
' 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 &=
String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
' *** 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 &=
String.Format(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/en-us/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.
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 for System.Threading.
using System.Threading;
namespace CancelATask
{
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
{
// ***Send a token to carry the message if cancellation is requested.
int contentLength = await AccessTheWebAsync(cts.Token);
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
}
// *** If cancellation is requested, an OperationCanceledException results.
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownload canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownload failed.\r\n";
}
// ***Set the CancellationTokenSource to null when the download is complete.
cts = null;
}
// ***Add an event handler for the Cancel button.
private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}
// ***Provide a parameter for the CancellationToken.
async Task<int> AccessTheWebAsync(CancellationToken ct)
{
HttpClient client = new HttpClient();
resultsTextBox.Text +=
String.Format("\r\nReady to download.\r\n");
// You might need to slow things down to have a chance to cancel.
await Task.Delay(250);
// GetAsync returns a Task<HttpResponseMessage>.
// ***The ct argument carries the message if the Cancel button is chosen.
HttpResponseMessage response = await client.GetAsync("https://msdn.microsoft.com/en-us/library/dd470362.aspx", ct);
// Retrieve the website contents from the HttpResponseMessage.
byte[] urlContents = await response.Content.ReadAsByteArrayAsync();
// The result of the method is the length of the downloaded website.
return urlContents.Length;
}
}
// Output for a successful download:
// Ready to download.
// Length of the downloaded string: 158125.
// Or, if you cancel:
// Ready to download.
// Download canceled.
}
取消任务的示例列出
下面的代码是取消任务列表示例的完整 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件。
' 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 &=
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
' 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.
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 for System.Threading.
using System.Threading;
namespace CancelAListOfTasks
{
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
{
await AccessTheWebAsync(cts.Token);
// ***Small change in the display lines.
resultsTextBox.Text += "\r\nDownloads complete.";
}
catch (OperationCanceledException)
{
resultsTextBox.Text += "\r\nDownloads canceled.";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.";
}
// Set the CancellationTokenSource to null when the download is complete.
cts = null;
}
// Add an event handler for the Cancel button.
private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}
// Provide a parameter for the CancellationToken.
// ***Change the return type to Task because the method has no return statement.
async Task AccessTheWebAsync(CancellationToken ct)
{
// Declare an HttpClient object.
HttpClient client = new HttpClient();
// ***Call SetUpURLList to make a list of web addresses.
List<string> urlList = SetUpURLList();
// ***Add a loop to process the list of web addresses.
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 can cancel 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);
}
}
// ***Add a method that creates a list of web addresses.
private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"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;
}
}
// 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.
}
请参见
参考
概念
使用 Async 和 Await 的异步编程(C# 和 Visual Basic)