BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Parallel and Asynchronous
.NET 4.0+

Cancelling Parallel Loops

The Task Parallel Library includes static methods that provide parallel equivalents of the for and foreach loops. As with parallel tasks, these loops can be cancelled by other processes using a system of cancellation tokens.

OperationCanceledException

When a parallel loop is cancelled it throws an OperationCanceledException. You should capture this exception and, in an appropriate catch block, you should perform any clean-up operation. In our case when the loop is cancelled we will change the progress bar back to the marquee style, making the bar show an animation that hides its current value.

The code for the loop and a try / catch block that handles the exception and resets the progress bar style is shown below. In this case only cancellation exceptions are handled. In a real-world application you should also catch AggregateExceptions, which contain the details of problems that happened during the loop iterations. NB: It is possible for an AggregateException from a parallel loop to contain OperationCanceledExceptions if the loop spawned new tasks that were cancelled.

try
{
    Parallel.For(1, 101, options, i =>
    {
        Thread.Sleep(100);

        lock (_lock)
        {
            Invoke((Action)delegate { Progress.Value++; });
        }
    });
}
catch (OperationCanceledException)
{
    Invoke((Action)delegate
    {
        Progress.Style = ProgressBarStyle.Marquee;
    });
}

Once the loop has completed or been cancelled, we need to reset the Enabled properties of the two buttons. To do so, add the following code after the catch block. You can see that if the loop is allowed to complete normally, the style of the progress bar will remain as "Continuous", so the bar will be left completely filled.

Invoke((Action)delegate
{
    StartProcessButton.Enabled = true;
    CancelProcessButton.Enabled = false;
});

Adding the Cancel Button Code

Finally we need to add the code to cancel the loop when the Cancel button is clicked. This just requires that we call the Cancel method of the cancellation token source. Double click the Cancel button to create a Click event handler and add the following code:

_tokenSource.Cancel();

You can now run the program to test it. Try clicking the Start button several times, cancelling the process or allowing the loop to complete to see the results.

26 December 2011