# Basic task cancellation demo in C#

Here we’ll look at a very basic example of a cancellable Task. This is an addition to the post Synchronous to asynchronous in .NET. This is a complete runnable code demo of a simple Console application that runs a slow process asynchronously. User has an option to “Press C” to cancel the operation.

We’ll first have the actual synchronous method CancellableWork() that is invoked asynchronously. It accepts a CancellationToken and periodically checks if cancellation is requested on the token. If requested, it aborts the operation and throws a TaskCanceledException.

The method CancellableTask() starts the operation asynchronously and passes a cancellation token. It then retunes the resulting Task to the calling method. So, the calling method can pass a CancellationToken while invoking this method and request a cancellation later.

Note: Just passing a CancellationToken and requesting a Cancel() doesn’t do much by itself. It’s up to the actual working logic to check and respond to IsCancellationRequested. Also, the code decides whether to throw a TaskCanceledException by convention, or not.

private void CancellableWork(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("Cancelled work before start");
cancellationToken.ThrowIfCancellationRequested();
}

for (int i = 0; i < 10; i++)
{
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine($"Cancelled on iteration # {i + 1}"); //the following lien alone is enough to check and throw cancellationToken.ThrowIfCancellationRequested(); } Console.WriteLine($"Iteration # {i + 1} completed");
}
}

{
}


Now we look at the Main() method of the application that invokes our CancellableTask() method with a cancellation token. If user presses C, cancellation is requested to the method.

Then we Wait() for the Task to complete. We also do try-catch to look for any exception. If we get a TaskCanceledException in the AggregateException thrown by the task, we know (by convention only), that the task was aborted because of the requested cancellation.

static void Main(string[] args)
{
Console.WriteLine("Starting application...");

CancellationTokenSource source = new CancellationTokenSource();
//assuming the wrapping class is TplTest

Console.WriteLine("Heavy process invoked");

Console.WriteLine("Press C to cancel");
Console.WriteLine("");
if (ch == 'c' || ch == 'C')
{
source.Cancel();
}

try
{
}
catch (AggregateException ae)
{
if (ae.InnerExceptions.Any(e => e is TaskCanceledException))
else
throw;
}
catch (Exception)
{
throw;
}
finally
{
source.Dispose();
}

Console.WriteLine("Process completed");
}


This program generates the following output.

Starting application...
Heavy process invoked
Press C to cancel

Iteration # 1 completed
Iteration # 2 completed
Iteration # 3 completed
c