【问题标题】:c# async task cancellationc# 异步任务取消
【发布时间】:2016-10-28 12:59:23
【问题描述】:

我在掌握任务和取消标记时遇到了一些问题。我制作了一个如下所示的程序:

static void Main(string[] args)
{

    CancellationTokenSource token = new CancellationTokenSource();
    Stopwatch stop = new Stopwatch();
    stop.Start();

    for (int i = 0; i < 5; i++)
    {
        //Thread.Sleep(1000);
        Task.Factory.StartNew(() => myLongTask(token.Token, (i + 1) * 1000));
    }
    while (true)
    {
        Thread.SpinWait(1000);
        if (stop.ElapsedMilliseconds > 3000)
        {
            token.Cancel();
        }
    }
}

public static void myLongTask(CancellationToken token, int time)
{
    if (token.IsCancellationRequested)
    {
        Console.WriteLine("Cancelled");
        return;
    }
    var sw = Stopwatch.StartNew();
    Console.WriteLine($"Task {time / 1000} started");
    while (sw.ElapsedMilliseconds < time)
        Thread.SpinWait(1000);
    Console.WriteLine($"Task {time / 1000} ended");

}

我同时运行 5 个任务(尽管当我不包括 Thread.Sleep() 时,for 循环似乎在任务开始之前运行?)。当我运行程序时,没有任何任务被取消。还有什么困扰着我......当我打电话给token.Cancel() 时,我真正取消了什么任务?我如何选择我要杀死的 5 个任务中的哪一个?我可以通过它的变量定义每个任务,但我无法访问它的CancellationRequested 属性,因为它是由CancellationToken 触发的。那我需要 5 个不同的令牌吗?

【问题讨论】:

    标签: c# multithreading asynchronous task cancellationtokensource


    【解决方案1】:

    当我运行程序时,没有任何任务被取消。

    那是因为您只在任务的开始 处检查取消标记。一旦通过了第一次token.IsCancellationRequested 检查,取消令牌就没有任何作用。如果您将检查移到循环中,如下所示:

    while (sw.ElapsedMilliseconds < time)
    {
        if (token.IsCancellationRequested)
        {
            Console.WriteLine("Cancelled");
            return;
        }
        Thread.SpinWait(1000);
    }
    

    ...然后您会看到任务做出适当的反应。

    还有什么困扰着我......当我打电话给token.Cancel() 时,我真正取消了什么任务?

    您不是在取消任务 - 您是在取消取消令牌。 观察到该取消令牌的任何任务都将被取消(或完成,或采取的任何操作),但任务和令牌之间没有直接关联。

    当我们谈论“取消任务”时,我们真正的意思是“取消我们认为任务正在观察的令牌”。

    【讨论】:

    • 但是如果我有 5 个不同的任务并且只有一个 token.Cancel()...那么它显然会取消所有 5 个任务?如果我想杀死一个特定的任务,我需要一个令牌列表吗?
    • @Norgul:是的,你会的。或者至少,您需要 5 个不同的标记和某种方法来了解您想要停止的任务正在观察哪个标记。
    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多