13

我想知道使用 CancellationTokenSource 结束循环任务和退出标志之间是否有任何区别

取消令牌来源:

CancellationTokenSource cancellationTokenSource;
Task loopTask;

void StartLoop()
{
    cancellationTokenSource = new CancellationTokenSource();
    loopTask = Task.Factory.StartNew(Loop, TaskCreationOptions.LongRunning);
}

void Loop()
{
    while (true)
    {
        if (cancellationTokenSource.IsCancellationRequested)
            break;

        Thread.Yield();
    }
}

void StopLoop()
{
    cancellationTokenSource.Cancel();

    loopTask = null;
    cancellationTokenSource = null;
}

退出标志:

volatile bool exitLoop;
Task loopTask;

void StartLoop()
{
    exitLoop = false;
    loopTask = Task.Factory.StartNew(Loop, TaskCreationOptions.LongRunning);
}

void Loop()
{
    while (true)
    {
        if (exitLoop)
            break;

        Thread.Yield();
    }
}

void StopLoop()
{
    exitLoop = true;

    loopTask = null;
}

对我来说,使用 CancellationTokenSource 没有任何意义,顺便说一句,有什么理由可以将取消令牌作为参数添加到任务工厂?

非常感谢您的任何回答。

最好的 ragards teamol

4

1 回答 1

13
  1. 使用 aCancellationToken允许令牌处理所有必要的同步,因此您不必考虑它。
  2. Task由于创建时使用的令牌被标记为已取消而导致故障时,它会将状态设置Task为已取消,而不是故障。如果您使用布尔值(并且不抛出),则该任务实际上会被标记为成功完成,即使它实际上已被取消。
  3. 与布尔值不同,它是一种引用类型,因此对 CTS 的引用可以从其他位置传递和取消(或检查)。这是关键,因为这些位置不需要像使用布尔字段时那样耦合在一起;决定何时取消操作的代码和任何对取消做出反应的代码都不需要相互了解。这允许更大的模块化、抽象化、更高级别的功能,而不是特定于个人情况等。
  4. 它为代码添加了增强的语义含义。
于 2015-01-14T19:31:41.737 回答