C#取消令牌作为任务第二个参数

时间:2016-10-31 11:17:09

标签: c# multithreading asynchronous task cancellation-token

如何通过在任务内转发令牌而不是在任务调用的方法内取消长时间运行的任务?

我的代码:

class Program
{
    static void Main(string[] args)
    {
        CancellationTokenSource token = new CancellationTokenSource();
        Stopwatch stop = new Stopwatch();
        stop.Start();

        Task.Factory.StartNew(() => myLongTask(6000), token.Token);

        while (true)
        {
            Thread.SpinWait(1000);
            if (stop.ElapsedMilliseconds > 3000)
            {
                token.Cancel();
            }
        }
    }

    public static void myLongTask(int time)
    {
        var sw = Stopwatch.StartNew();
        Console.WriteLine("Task started");
        while (true)
        { }
        Console.WriteLine("Task ended");
    }
}

此任务永远不会被取消。如果我在myLongTask()方法中转发令牌,我可以连续听取取消是否被触发,但是,我不确定......你怎么能这样做呢?

1 个答案:

答案 0 :(得分:1)

您需要自己检查令牌的状态,例如:

public static void myLongTask(int time, CancellationToken token)
{
    var sw = Stopwatch.StartNew();
    Console.WriteLine("Task started");
    while (true)
    { 
      token.ThrowIfCancellationRequested();
    }
    Console.WriteLine("Task ended");
}

正如评论中所提到的,其原因在于取消是一种合作行动。它不是框架必须强制你的任务停止,这可能会使你的应用程序处于不良状态。通过检查自己,您可以完全控制取消操作的含义。