Cancel Async Tasks after a Period of Time (Visual Basic)

You can cancel an asynchronous operation after a period of time by using the CancellationTokenSource.CancelAfter method if you don't want to wait for the operation to finish. This method schedules the cancellation of any associated tasks that aren’t complete within the period of time that’s designated by the CancelAfter expression.

This example adds to the code that’s developed in Cancel an Async Task or a List of Tasks (Visual Basic) to download a list of websites and to display the length of the contents of each one.

Note

To run the examples, you must have Visual Studio 2012 or later and the .NET Framework 4.5 or later installed on your computer.

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.

  1. Decompress the file that you downloaded, and then start Visual Studio.

  2. On the menu bar, choose File, Open, Project/Solution.

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

  4. In Solution Explorer, open the shortcut menu for the CancelAfterTime project, and then choose Set as StartUp Project.

  5. Choose the F5 key to run the project.

    Choose the Ctrl+F5 keys to run the project without debugging it.

  6. Run the program several times to verify that the output might show output for all websites, no websites, or some web sites.

If you don't want to download the project, you can review the MainWindow.xaml.vb file at the end of this topic.

Building the Example

The example in this topic adds to the project that's developed in Cancel an Async Task or a List of Tasks (Visual Basic) to cancel a list of tasks. The example uses the same UI, although the Cancel button isn’t used explicitly.

To build the example yourself, step by step, follow the instructions in the "Downloading the Example" section, but choose CancelAListOfTasks as the StartUp Project. Add the changes in this topic to that project.

To specify a maximum time before the tasks are marked as canceled, add a call to CancelAfter to startButton_Click, as the following example shows. The addition is marked with asterisks.

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

Run the program several times to verify that the output might show output for all websites, no websites, or some web sites. The following output is a sample:

Length of the downloaded string: 35990.

Length of the downloaded string: 407399.

Length of the downloaded string: 226091.

Downloads canceled.

Complete Example

The following code is the complete text of the MainWindow.xaml.vb file for the example. Asterisks mark the elements that were added for this example.

Notice that you must add a reference for System.Net.Http.

You can download the project from Async Sample: Fine Tuning Your Application.

' 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 &=
                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

' Sample output:

' Length of the downloaded string: 35990.

' Length of the downloaded string: 407399.

' Length of the downloaded string: 226091.

' Downloads canceled.

See also