为什么Task.Factory.StartNew()需要使用CancellationToken重载?

isp*_*iro 1 .net c# multithreading

我创建了一个以CancellationToken作为参数的方法,并在Task中使用了它,一切正常。那么,为什么令牌会过载StartNew呢?它有一定的效果,以防止可能的竞争条件下,我的代码没有,因此在其他情况下是必要的?

为什么 Task.Factory.StartNew(() => DoNow(), cancellationTokenSource.Token);

而不是:Task.Factory.StartNew(() => DoNow(cancellationTokenSource.Token));

Den*_*nis 5

在您发布的链接中查看参数说明:

将分配给新任务的CancellationToken。

此处分配了关键字。这是令牌传递给时的示例StartNew

        var cts1 = new CancellationTokenSource();
        var t1 = Task
            .Factory
            .StartNew(() =>
            {
                cts1.Cancel();
                cts1.Token.ThrowIfCancellationRequested();
            }, cts1.Token)
            // this continuation will be fired
            .ContinueWith(t => Console.WriteLine("t1 was cancelled"), TaskContinuationOptions.OnlyOnCanceled);
Run Code Online (Sandbox Code Playgroud)

另一个没有通过:

        var cts2 = new CancellationTokenSource();
        var t2 = Task
            .Factory
            .StartNew(() =>
            {
                cts2.Cancel();
                cts2.Token.ThrowIfCancellationRequested();
            })
            // this continuation will **not** be fired
            .ContinueWith(t => Console.WriteLine("t2 was cancelled"), TaskContinuationOptions.OnlyOnCanceled);
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,您将进入OperationCancelledException任务主体,但不会触发继续操作,因为任务不会进入Cancelled状态。取而代之的是,任务状态将为Faulted,这很明显,如果您的代码区分了这两种状态,那就是错误的。