Cancel an Async Task or a List of Tasks (Visual Basic)
You can set up a button that you can use to cancel an async application if you don't want to wait for it to finish. By following the examples in this topic, you can add a cancellation button to an application that downloads the contents of one website or a list of websites.
The examples use the UI that Fine-Tuning Your Async Application (Visual Basic) describes.
Note
To run the examples, you must have Visual Studio 2012 or newer and the .NET Framework 4.5 or newer installed on your computer.
Cancel a Task
The first example associates the Cancel button with a single download task. If you choose the button while the application is downloading content, the download is canceled.
Downloading the Example
You can download the complete Windows Presentation Foundation (WPF) project from Async Sample: Fine Tuning Your Application and then follow these steps.
Decompress the file that you downloaded, and then start Visual Studio.
On the menu bar, choose File, Open, Project/Solution.
In the Open Project dialog box, open the folder that holds the sample code that you decompressed, and then open the solution (.sln) file for AsyncFineTuningVB.
In Solution Explorer, open the shortcut menu for the CancelATask project, and then choose Set as StartUp Project.
Choose the F5 key to run the project.
Choose the Ctrl+F5 keys to run the project without debugging it.
If you don't want to download the project, you can review the MainWindow.xaml.vb files at the end of this topic.
Building the Example
The following changes add a Cancel button to an application that downloads a website. If you don't want to download or build the example, you can review the final product in the "Complete Examples" section at the end of this topic. Asterisks mark the changes in the code.
To build the example yourself, step by step, follow the instructions in the "Downloading the Example" section, but choose StarterCode as the StartUp Project instead of CancelATask.
Then add the following changes to the MainWindow.xaml.vb file of that project.
Declare a
CancellationTokenSource
variable,cts
, that’s in scope for all methods that access it.Class MainWindow ' ***Declare a System.Threading.CancellationTokenSource. Dim cts As CancellationTokenSource
Add the following event handler for the Cancel button. The event handler uses the CancellationTokenSource.Cancel method to notify
cts
when the user requests cancellation.' ***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
Make the following changes in the event handler for the Start button,
startButton_Click
.Instantiate the
CancellationTokenSource
,cts
.' ***Instantiate the CancellationTokenSource. cts = New CancellationTokenSource()
In the call to
AccessTheWebAsync
, which downloads the contents of a specified website, send the CancellationTokenSource.Token property ofcts
as an argument. TheToken
property propagates the message if cancellation is requested. Add a catch block that displays a message if the user chooses to cancel the download operation. The following code shows the changes.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
In
AccessTheWebAsync
, use the HttpClient.GetAsync(String, CancellationToken) overload of theGetAsync
method in the HttpClient type to download the contents of a website. Passct
, the CancellationToken parameter ofAccessTheWebAsync
, as the second argument. The token carries the message if the user chooses the Cancel button.The following code shows the changes in
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
If you don’t cancel the program, it produces the following output:
Ready to download. Length of the downloaded string: 158125.
If you choose the Cancel button before the program finishes downloading the content, the program produces the following output:
Ready to download. Download canceled.
Cancel a List of Tasks
You can extend the previous example to cancel many tasks by associating the same CancellationTokenSource
instance with each task. If you choose the Cancel button, you cancel all tasks that aren’t yet complete.
Downloading the Example
You can download the complete Windows Presentation Foundation (WPF) project from Async Sample: Fine Tuning Your Application and then follow these steps.
Decompress the file that you downloaded, and then start Visual Studio.
On the menu bar, choose File, Open, Project/Solution.
In the Open Project dialog box, open the folder that holds the sample code that you decompressed, and then open the solution (.sln) file for AsyncFineTuningVB.
In Solution Explorer, open the shortcut menu for the CancelAListOfTasks project, and then choose Set as StartUp Project.
Choose the F5 key to run the project.
Choose the Ctrl+F5 keys to run the project without debugging it.
If you don't want to download the project, you can review the MainWindow.xaml.vb files at the end of this topic.
Building the Example
To extend the example yourself, step by step, follow the instructions in the "Downloading the Example" section, but choose CancelATask as the StartUp Project. Add the following changes to that project. Asterisks mark the changes in the program.
Add a method to create a list of web addresses.
' ***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
Call the method in
AccessTheWebAsync
.' ***Call SetUpURLList to make a list of web addresses. Dim urlList As List(Of String) = SetUpURLList()
Add the following loop in
AccessTheWebAsync
to process each web address in the list.' ***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
Because
AccessTheWebAsync
displays the lengths, the method doesn't need to return anything. Remove the return statement, and change the return type of the method to Task instead of Task<TResult>.Async Function AccessTheWebAsync(ct As CancellationToken) As Task
Call the method from
startButton_Click
by using a statement instead of an expression.Await AccessTheWebAsync(cts.Token)
If you don’t cancel the program, it produces the following output:
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.
If you choose the Cancel button before the downloads are complete, the output contains the lengths of the downloads that completed before the cancellation.
Length of the downloaded string: 35939. Length of the downloaded string: 237682. Length of the downloaded string: 128607. Downloads canceled.
Complete Examples
The following sections contain the code for each of the previous examples. Notice that you must add a reference for System.Net.Http.
You can download the projects from Async Sample: Fine Tuning Your Application.
Cancel a Task Example
The following code is the complete MainWindow.xaml.vb file for the example that cancels a single task.
' 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.
Cancel a List of Tasks Example
The following code is the complete MainWindow.xaml.vb file for the example that cancels a list of tasks.
' 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.