取消异步任务或任务列表 (Visual Basic)

如果不想等待异步应用程序完成,可以设置可用于取消异步应用程序的按钮。 通过遵循本主题中的示例,可以将取消按钮添加到下载一个网站或网站列表的应用程序。

这些示例使用了Fine-Tuning Your Async Application (Visual Basic) 中描述的 UI。

注释

若要运行这些示例,必须在计算机上安装 Visual Studio 2012 或更高版本以及 .NET Framework 4.5 或更高版本。

取消任务

第一个示例将 “取消” 按钮与单个下载任务相关联。 如果在应用程序下载内容时选择该按钮,则会取消下载。

下载示例

可以从异步示例下载完整的 Windows Presentation Foundation (WPF) 项目 :微调应用程序 ,然后执行以下步骤。

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

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

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

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

  5. 选择要运行项目的 F5 键。

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

如果不想下载项目,可以在本主题末尾查看MainWindow.xaml.vb文件。

生成示例

以下更改将“ 取消” 按钮添加到下载网站的应用程序。 如果不想下载或生成示例,可以在本主题末尾的“完整示例”部分查看最终产品。 星号标记代码中的更改。

若要自行生成示例,请逐步按照“下载示例”部分中的说明进行作,但选择 StarterCode 作为 StartUp 项目 而不是 CancelATask

然后将以下更改添加到该项目的MainWindow.xaml.vb文件中。

  1. 声明一个 CancellationTokenSource 变量, cts该变量位于访问该变量的所有方法的范围内。

    Class MainWindow
    
        ' ***Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
  2. “取消” 按钮添加以下事件处理程序。 事件处理程序使用 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
    
  3. “开始” 按钮 startButton_Click的事件处理程序中进行以下更改。

    • 实例化CancellationTokenSourcects

      ' ***Instantiate the CancellationTokenSource.
      cts = New CancellationTokenSource()
      
    • 在调用AccessTheWebAsync时,该调用用于下载指定网站的内容,请将CancellationTokenSource.Tokencts属性作为参数发送。 如果请求取消,该 Token 属性将传播消息。 添加一个 catch 块,当用户选择取消下载作时显示一条消息。 以下代码显示了这些更改。

      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. AccessTheWebAsync 中,使用 HttpClient.GetAsync(String, CancellationToken) 类型中 GetAsync 方法的 HttpClient 重载来下载网站内容。 将 ctCancellationTokenAccessTheWebAsync 参数)作为第二个参数传递。 如果用户选择 “取消” 按钮,令牌将传递消息。

    以下代码显示了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. 如果未取消程序,它将生成以下输出:

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

    如果在程序完成下载内容之前选择 “取消 ”按钮,程序将生成以下输出:

    Ready to download.
    Download canceled.
    

取消任务列表

可以通过将同一 CancellationTokenSource 实例与每个任务相关联来扩展上一个示例来取消许多任务。 如果选择 “取消 ”按钮,则取消尚未完成的所有任务。

下载示例

可以从异步示例下载完整的 Windows Presentation Foundation (WPF) 项目 :微调应用程序 ,然后执行以下步骤。

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

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

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

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

  5. 选择要运行项目的 F5 键。

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

如果不想下载项目,可以在本主题末尾查看MainWindow.xaml.vb文件。

生成示例

若要自行扩展示例,请逐步遵循“下载示例”部分中的说明进行操作,但选择 CancelATask 作为 启动项目。 将以下更改添加到该项目。 星号标记程序中的更改。

  1. 添加用于创建 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. AccessTheWebAsync中调用该方法。

    ' ***Call SetUpURLList to make a list of web addresses.
    Dim urlList As List(Of String) = SetUpURLList()
    
  3. 添加以下循环 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 &=
            vbCrLf & $"Length of the downloaded string: {urlContents.Length}." & vbCrLf
    Next
    
  4. 由于 AccessTheWebAsync 显示长度,因此该方法不需要返回任何内容。 删除 return 语句,并将方法的返回类型更改为 Task 而不是 Task<TResult>

    Async Function AccessTheWebAsync(ct As CancellationToken) As Task
    

    使用语句而不是表达式从 startButton_Click 中调用方法。

    Await AccessTheWebAsync(cts.Token)
    
  5. 如果未取消程序,它将生成以下输出:

    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 添加引用。

可以从 异步示例:微调应用程序 中下载项目。

取消任务示例

以下代码是取消单个任务的示例的完整MainWindow.xaml.vb文件。

' 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.

取消任务列表的示例

以下代码是取消任务列表的示例的完整MainWindow.xaml.vb文件。

' 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.

另请参阅