Cancel an async task

Published 12/20/2018 by Christian in Code
Tags: , , ,

So, I wanted to do asynchronously database search that could take a long time. But if the user refine her search criteria, the async should restart, and whatever already found records be disregarded.

Using the following Microsoft article as a template, this is what I came up with as a proof of concept.

 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/cancel-an-async-task-or-a-list-of-tasks

 

This WPF program has 3 buttons. 

Start - will cancel all already started jobs, waits for 5 sec. and then download some content from a msdn site.

Cancel All - will simply cancel all started jobs.

Clear - will cancel all started jobs, and clear any messages.

 

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;

// 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.
        List<CancellationTokenSource> cts = new List<CancellationTokenSource>();

        public MainWindow()
        {
            InitializeComponent();
        }


        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            cts?.ForEach(c => c.Cancel());
            // ***Instantiate the CancellationTokenSource.
            using (CancellationTokenSource c = new CancellationTokenSource())
            {
                cts.Add(c);

                try
                {
                    // ***Send a token to carry the message if cancellation is requested.
                    int contentLength = await AccessTheWebAsync(c.Token);
                    resultsTextBox.Text += $"\r\nLength of the downloaded string: {contentLength}.\r\n";
                }
                // *** If cancellation is requested, an OperationCanceledException results.
                catch (OperationCanceledException)
                {
                    resultsTextBox.Text += $"\r\nDownload canceled. Current no of jobs: {cts.Count}\r\n";
                }
                catch (Exception)
                {
                    resultsTextBox.Text += "\r\nDownload failed.\r\n";
                }
                cts.Remove(c);
            }
        }


        // ***Add an event handler for the Cancel button.
        private void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            cts?.ForEach(c => c.Cancel());
        }

        private void clearButton_Click(object sender, RoutedEventArgs e)
        {
            cts?.ForEach(c => c.Cancel());
            resultsTextBox.Clear();
        }

        // ***Provide a parameter for the CancellationToken.
        async Task<int> AccessTheWebAsync(CancellationToken c)
        {
            HttpClient client = new HttpClient();

            resultsTextBox.Text += "Waiting for download to commence.\r\n";

            // You might need to slow things down to have a chance to cancel.
            await Task.Delay(5000, c);

            resultsTextBox.Text += "Commencing to download.\r\n";
            // GetAsync returns a Task<HttpResponseMessage>. 
            // ***The c argument carries the message if the Cancel button is chosen.
            HttpResponseMessage response = await client.GetAsync("http://msdn.microsoft.com/en-us/library/dd470362.aspx", c);

            // Retrieve the website contents from the HttpResponseMessage.
            byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

            // The result of the method is the length of the downloaded web site.
            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.
}

 

As always feel free to ask or comment.


Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading