Boopal S
Boopal S

Reputation: 133

How to cancel a task from different class

I want to cancel a task started by one class from some other class. Below is an example program where i have two classes and want to cancel the task from different class. Cancellation token doesn't seem to work.

namespace threadingiwthcancel
{
    class ThreadExample
    {
        public async Task PrintSomething(CancellationToken token)
        {
            int i = 0;
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Cancel requested");
                    break;
                }
                await Task.Delay(TimeSpan.FromSeconds(1));
                Console.WriteLine(i);
                i++;
            }

        }
    }
    class Cancel
    {
        public void cancelTask()
        {
            CancellationTokenSource source = new CancellationTokenSource();
            source.Cancel();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            callasyncmethod(token);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Cancel c = new Cancel();
            c.cancelTask();
            Console.ReadLine();
        }

        private static async void callasyncmethod(CancellationToken token)
        {
            ThreadExample te = new ThreadExample();
            await te.PrintSomething(token);
        }
    }
}

Upvotes: 3

Views: 1755

Answers (2)

user585968
user585968

Reputation:

Cancellation token doesnt seem to work.

The reason for failure is that you are creating a different CancellationTokenSource and calling Cancel on it. Sadly, no other operations will be notified and so your original task continues.

I want to cancel a task started by one class from some other class

Be sure to pass the original source to it:

class Cancel
{
    CancellationTokenSource _source;

    public Cancel (CancellationTokenSource source)
    {
       _source = source;
    }

    public void cancelTask()
    {            
        _source.Cancel();
    }
}

    static void Main(string[] args)
    {
        CancellationTokenSource source = new CancellationTokenSource();
        CancellationToken token = source.Token;
        callasyncmethod(token);
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Cancel c = new Cancel(source); // pass in the original source
        c.cancelTask();
        Console.ReadLine();
    }

Upvotes: 2

Pranay Rana
Pranay Rana

Reputation: 176896

if you want to do like that than you need to pass object of CancellationSoruce to you cancel method in other class , do not create new CancellationSoruce

class Cancel
{      
 public void cancelTask(CancellationTokenSource source )
    {
        source.Cancel();
    }
}

in main

static void Main(string[] args)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            callasyncmethod(token);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Cancel c = new Cancel();
            c.cancelTask(source );
            Console.ReadLine();
        }

or can do like this

  class Cancel
    {   
        private readonly CancellationTokenSource source;
        public Cancel(CancellationTokenSource source)
        {
          this.source = soruce;
        }   
        public void cancelTask()
        {
            source.Cancel();
        }
    }

and in main

static void Main(string[] args)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            callasyncmethod(token);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Cancel c = new Cancel(source );
            c.cancelTask();
            Console.ReadLine();
        }

Upvotes: 0

Related Questions