如何从不同的类中取消任务

时间:2017-12-06 06:34:28

标签: c# task

我想取消一个类从其他类开始的任务。下面是一个示例程序,其中我有两个类,并希望从不同的类中取消任务。取消令牌似乎不起作用。

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);
        }
    }
}

2 个答案:

答案 0 :(得分:2)

  

取消令牌似乎无效。

失败的原因是您正在创建不同 CancellationTokenSource并在其上调用Cancel。可悲的是,没有其他操作会被通知,因此您的原始任务将继续。

  

我想取消一个类从其他类开始的任务

请务必将原始来源传递给它:

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();
    }

答案 1 :(得分:0)

如果您想要这样做而不是需要将CancellationSoruce的对象传递给其他类中的取消方法,请不要创建新的CancellationSoruce

class Cancel
{      
 public void cancelTask(CancellationTokenSource source )
    {
        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();
            c.cancelTask(source );
            Console.ReadLine();
        }

或者可以这样做

  class Cancel
    {   
        private readonly CancellationTokenSource source;
        public Cancel(CancellationTokenSource source)
        {
          this.source = soruce;
        }   
        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 );
            c.cancelTask();
            Console.ReadLine();
        }