Search code examples
c#async-awaitcancellation-token

How can I cancel a Task without LOOP


Hi I've been reading alot on the forum but I'm not able to find the answer to my problem...

Here's my function that I want to cancel when a boolean turn to TRUE:

Task<PortalODataContext> task = Task.Factory.StartNew(() =>
        {
            var context = connection.ConnectToPortal();
            connection.ListTemplateLib = this.ShellModel.ConnectionManager.GetTemplateLibrarys(connection);
            connection.ListTemplateGrp = this.ShellModel.ConnectionManager.GetTemplateGroups(connection, connection.TemplateLibraryId);
            connection.ListTemplates = this.ShellModel.ConnectionManager.GetTemplates(connection, connection.TemplateGroupId);
            return context;
       }, token);

How can I verify if the token got a cancel request without a LOOP ?

Something like that :

if (token.IsCancellationRequested)
{
    Console.WriteLine("Cancelled before long running task started");
    return;
}

for (int i = 0; i <= 100; i++)
{
    //My operation

    if (token.IsCancellationRequested)
    {
        Console.WriteLine("Cancelled");
        break;
    }
}

But I dont have an operation that require a Loop so I dont know how to do that ...


Solution

  • I'm assuming token is a CancellationToken?

    You wouldn't need a loop, instead take a look at CancellationToken.ThrowIfCancellationRequested. By calling this, the CancellationToken class will check if it has been canceled, and kill the task by throwing an exception.

    Your task code would then turn into something like:

    using System.Threading.Tasks;
    Task.Factory.StartNew(()=> 
    {
        // Do some unit of Work
        // .......
    
        // now check if the task has been cancelled.
        token.ThrowIfCancellationRequested();
    
        // Do some more work
        // .......
    
        // now check if the task has been cancelled.
        token.ThrowIfCancellationRequested();
    }, token);
    

    If the cancellation exception is thrown, the task returned from Task.Factory.StartNew will have its IsCanceled property set. If you're using async/await, you'll need to catch the OperationCanceledException and clean things up appropriately.

    Check out the Task Cancellation page on MSDN for more info.