在一段时间后取消异步任务(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) 项目,然后按照这些步骤操作。

  1. 解压下载的文件,然后启动 Visual Studio。

  2. 在菜单栏上,依次选择**“文件”“打开”“项目/解决方案”**。

  3. 在“打开项目”对话框中,打开包含您解压缩的示例代码的文件夹,然后打开 AsyncFineTuningCS 或 AsyncFineTuningVB 的解决方案 (.sln) 文件。

  4. 在“解决方案资源管理器”中,打开“CancelAfterTime”项目的快捷菜单,然后选择“设置为启动项目”。

  5. 选择 F5 键运行项目。

    选择 Ctrl+F5 键运行项目,但不对其进行调试。

  6. 多次运行程序以验证输出可以显示所有网站、无网站和部分网站的输出。

如果您不希望下载该项目,可以在本主题结尾查看 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)

微调异步应用程序(C# 和 Visual Basic)

其他资源

Async Sample: Fine Tuning Your Application