Click here to Skip to main content
15,879,348 members
Articles / General Programming / Threads

Cancel a Loop in a Task with CancellationTokens

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
11 Mar 2014CPOL2 min read 28.2K   7  
Cancel a loop in a task with CancellationTokens

Introduction

In the event that you create an asynchronous Task with a loop, in which you run your code, say you’ve created an asynchronous task. The method you’re running inside your task contains a loop (infinite or not), and you want to break out of it, peacefully. You would need to create a CancellationTokenSource and pass the Task.Factory.StartNew method the cancellation Token, also passing the token to the main loop.

A CancellationTokenSource provides a way of signaling its Cancellation Token that it has been cancelled. A CancellationToken notifies the operation that it should be cancelled.

I am creating a new Task using the Factory property of the Task. I could have created it in a different way, check here for Task Constructors. I am also using the parameters TaskCreationOption.LongRunningTask and TaskScheduler.Default.

 

TaskCreationOption.LongRunningTask

Specifies that a task will be a long-running, coarse-grained operation involving fewer, larger components than fine-grained systems. It provides a hint to the TaskScheduler that oversubscription may be warranted. Oversubscription lets you create more threads than the available number of hardware threads.

TaskScheduler.Default

Gets the default TaskScheduler instance that is provided by the .NET Framework.

Here is a simple example on how to achieve this. You can run this code on LinqPad or create a new console project. Just remember to include the System.Threading.Tasks namespace.

C#
void Main()
{
    CancellationTokenSource cts = new CancellationTokenSource();
    var token = cts.Token;
    
    Task t = Task.Factory.StartNew( 
        () => {
        MainLoop(token);
        }, 
        token, 
        TaskCreationOptions.LongRunning, 
        TaskScheduler.Default
    );    
    
    Console.ReadLine();
    
    cts.Cancel();
    
    try 
    {
        t.Wait();
    }
    catch( AggregateException ae )
    {
        // catch inner exception 
    }
    catch( Exception crap )
    {
        // catch something else
    }
}

void MainLoop( CancellationToken token )
{
    while( true )
    {
        // do something here.
        Console.Write(".");
        Thread.Sleep(100);
        
        // Poll on this property if you have to do 
        // other cleanup before throwing. 
        if (token.IsCancellationRequested)
        {
            // Clean up here, then...
            "cleanup".Dump();
            token.ThrowIfCancellationRequested();
        }
    }
}

After creating the Task, it will start automatically. All you have to do is to wait for the result, in this case there won’t be any variable returned, but you have to do this so you can recover if you get an AggregatedException.

To cancel the Task, just call the method Cancel from the CancellationTokenSource. Inside your method, the IsCancellationRequested property from the token will be true, giving you time to do some cleanup before throwing the cancellation request.

That’s pretty much it.

Get more information about C# Tasks and the Task Parallelism Library.

I hope you enjoyed this little explanation. Tasks are way much more than this little code snippet, so if you’re interested, check back once in a while, I’ll put up more snippets.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United Kingdom United Kingdom
http://mikeadev.net/about-me/

Comments and Discussions

 
-- There are no messages in this forum --