CancellationToken is even null

CancellationToken is even null

In my application I run a Task which execute an heavy operation, I'm trying to stop the execution of that Task. Actually I declared in my class the following structure:

public class Foo
{
    private CancellationTokenSource tokenSource = new CancellationTokenSource();
    private CancellationToken token;

    public void Start()
    {
        var task = new Task(async () => {
           try
           {
               await new Bot().StartAsync(token);
           }
           catch(Exception ex)
           {
              Console.WriteLine(ex.ToString());
           }
        }, token));

        task.Start();
    }
}

as you can see I have declared a CancellationTokenSource which allow me to stop the task execution when the user click on a button:

StopTask_Click(object sender, EventArgs e) 
{
    tokenSource.Cancel();
}

Now, inside the StartAsync method I have the following code:

public async Task StartAsync(CancellationToken token)
{
    ApplicationToken = token;

    while(true)
    {
       if(ApplicationToken.IsCancellationRequested)
       {
           break;
       }
    }
}

The ApplicationToken store the token passed as parameter in the class of StartAsync method.

After the button click event, the request should be cancelled but nothing happen.

Then I check for each iteration if a cancellation request was made, but the variable value is even false.


Well, it seems that you forgot to token = tokenSource.Token;

Edit1: You should check for cancellation using ThrowIfCancellationRequested()

Edit2:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace CancellationTokenPOC
{
class Program
{
    public static async Task Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        TokenPOC t = new TokenPOC();
        var longRunningTask = Task.Factory.StartNew(async () =>
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i);
                t.token.ThrowIfCancellationRequested();

                await Task.Delay(10000);
            }

        });
        Console.ReadKey();
        t.source.Cancel();
        await Task.Delay(1000);
        Console.WriteLine("finishing");
    }
}

class TokenPOC
{
    public CancellationTokenSource source = new CancellationTokenSource();
    public CancellationToken token;
    public TokenPOC()
    {
        token = source.Token;
    }
}
}

This token gets cancelled and ends the program as expected...

CancellationToken.None Property (System.Threading), Property Value. CancellationToken. An empty cancellation token. Remarks. The cancellation token returned by this property cannot be canceled; that is, its  A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects. You create a cancellation token by instantiating a CancellationTokenSource object, which manages cancellation tokens retrieved from its CancellationTokenSource.Token property.


You are passing a different token than the one you are trying to cancel. You can eliminate

private CancellationToken token;

and instead pass in to StartAsync()

tokenSource.Token

Recommended patterns for CancellationToken, Propagate your CancellationToken to all the methods you call that they have to be prepared for a successful result even upon cancellation. NullReferenceException if the // caller omitted the argument because it's a struct. Recommended patterns for CancellationToken. Andrew . March 19th, 2014. Whether you’re doing async work or not, accepting a CancellationToken as a parameter to your method is a great pattern for allowing your caller to express lost interest in the result


Could you try the below:

public class Foo
{
   var cancellationTokenSource = new CancellationTokenSource();
   var token = cancellationTokenSource.Token();

   public void Start() {
        var t = Task.Factory.StartNew(() =>
        {
            try
            {
               await new Bot().StartAsync(token);
            }
            catch(Exception ex)
            {
               Console.WriteLine(ex.ToString());
            }
        }, token).ContinueWith(task =>
          {
              if (!task.IsCompleted || task.IsFaulted)
              {
                 // Log
              }
          }, token);
    }

    StopTask_Click(object sender, EventArgs e) 
    {
          cancellationTokenSource.Cancel();
    }
}

Using cancellation tokens, Starting from Hangfire 1.7.0 it's possible to use a regular CancellationToken class for to immediate storage requests so it's now safe to use it even in tight loops. as a background job, we can pass the null value as an argument for the token  @kosist You can use CancellationToken.None if you do not plan to cancel the operation you are starting manually. Of course when system process is killed, everything is interrupted and CancellationToken has nothing to do with that. So yes, you should only create CancellationTokenSource if you really need to use it to cancel the operation. There


First, StartAsync lacks await operators and it will run synchronously.

public async Task StartAsync(CancellationToken token)
{
    ApplicationToken = token;

    while (true)
    { 
        if (ApplicationToken.IsCancellationRequested) break;
        await Task.Delay(10, ApplicationToken); // => you may change it to concrete task
    }
}

Secondly, the CancellationToken at Foo class is redundant, you don't even initialize it.

new Bot().StartAsync(tokenSource.Token); inside Start method is not awaited so execution on the current method continues before the call is completed.

And since Start method is void you should use GetAwaiter() method in order to execute task at Bot class.

public void Start()
{
    try
    {
        new Bot().StartAsync(tokenSource.Token).GetAwaiter();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

Finally, if StopTask_Click method is member of Foo class, then it should works fine.


This is an example how to cancel the task using CancellationTokenSource

public partial class Form1 : Form
{
    private readonly Foo foo = new Foo();

    private void button1_Click(object sender, EventArgs e)
    {
        foo.Start();          
    }

    private void button2_Click(object sender, EventArgs e)
    {
        foo.Cancel();
    }
}

public class Foo
{
    private readonly CancellationTokenSource tokenSource = new CancellationTokenSource();

    public void Start()
    {
        try
        {
            new Bot().StartAsync(tokenSource.Token).GetAwaiter();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

    public void Cancel()
    {
        tokenSource.Cancel();
    }
}

public class Bot
{
    private CancellationToken ApplicationToken;

    public async Task StartAsync(CancellationToken token)
    {
        ApplicationToken = token;

        while (true)
        { 
            if (ApplicationToken.IsCancellationRequested) break;
            await Task.Delay(10, ApplicationToken);
        }
    }
}

Document that CancellationToken.None is default , You can definitely count on this being the case; even if we wanted to change it (​we don't), we Returns an empty CancellationToken value. How to catch CancellationToken.ThrowIfCancellationRequested. Ask Question Asked 3 years ago. Active 3 years ago. Viewed 2k times 0. 2. When this section of code is executed . cancellationToken.ThrowIfCancellationRequested(); The try catch block doesn't ha


Creating linked cancellation tokens hides which token triggered , The problem is that once you have a linked cancellation token, it will always isn​'t even correct since it may have been triggered elsewhere). CancellationTokenSource(); CancellationTokenSource linked = null; try { cts1. Why is my “Event” always null? Ask Question Asked 9 years, 9 months ago. Active 3 years, 3 months ago. Viewed 20k times 8. 1. I am trying to wire up a new event, but for some reason "Changed" is always evaluating to null. public class MyTreeViewItem


Cancel asynchronous operations in C#, As we sometimes need to cancel an ongoing asynchronous post, how to cancel tasks using CancellationToken, even for non-cancellable tasks. loop, CancellationToken cancellationToken) { Task<decimal> task = null;  Cancel asynchronous operations in C#. Running asynchronous code is pretty easy with .NET and C#. As we sometimes need to cancel an ongoing asynchronous operation we will see, throughout this post, how to cancel tasks using CancellationToken, even for non-cancellable tasks.


ListAccountsRequest, CancellationToken, These operations can occasionally return an empty set of results even when there are more results available. The NextToken response parameter value is null  AuthenticationHeaderValue authorization = request.Headers.Authorization; //This is always null even as I put [Authorize] tag above my controller Doesn't matter if I put [Authorize], [AllowAnonymous], authorization is always null. Looking for some help. Thanks in advance!