使用TaskFactory()与TaskFactory(CancellationToken)

时间:2018-01-10 20:42:15

标签: c# async-await task-parallel-library

当使用TaskFactory(默认构造函数)并且您希望任务可以取消时,您可以执行以下操作:

Task.Factory.StartNew(() => DoSomeWork(token), token);
// or the equivilant
var factory = new TaskFactory();
factory.StartNew(() => DoSomeWork(token), token);

根据MSDN,如果您使用TaskFactory()代替TaskFactory(CancellationToken),那么:

  

将分配给由此创建的任务的CancellationToken   TaskFactory,除非明确指定了另一个CancellationToken   同时调用工厂方法。

这让我相信我能做到这一点:

TaskFactory factory = new TaskFactory(token);
factory.StartNew(() => DoSomeWork(token)); // don't need to pass token to StartNew()
... // imagine a few more tasks created just like above
// now create a special task that marches to its own drummer (token)
factory.StartNew(() => DoSomeWork(differentToken), differentToken);

当然为什么我会这样做?仅使用Task.Factory.StartNew()进行一次性任务似乎更有意义(除非我有其他常见配置)。但我离题了。这就是我想到的,除了我在网上看到一些基本上看起来像这样的例子:

TaskFactory factory = new TaskFactory(token);
factory.StartNew(() => DoSomeWork(token), token);

将相同的令牌传递给StartNew(),因为工厂据称已配置为自动与此工厂创建的任务相关联。因此,我不确定我是否只是看到他们不需要做的工作的例子,或者如果有一些根本的东西我在这里有误解。毕竟,如果我要将令牌显式传递给StartNew(),那么将它传递给TaskFactory构造函数是什么意思?

1 个答案:

答案 0 :(得分:2)

以下是TaskFactory的{​​{3}}:

构造

public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
    CheckMultiTaskContinuationOptions(continuationOptions);
    CheckCreationOptions(creationOptions);

    m_defaultCancellationToken = cancellationToken;
    m_defaultScheduler = scheduler;
    m_defaultCreationOptions = creationOptions;
    m_defaultContinuationOptions = continuationOptions;
}

以下是没有CancellationToken参数的重载以及它是如何实现的:

[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable            
    public Task<TResult> StartNew<TResult>(Func<TResult> function)
    {
        StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
        Task currTask = Task.InternalCurrent;
        return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken,
            m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
    }

正如您所看到的那样,当您未使用带有m_defaultCancellationToken参数的CancellationToken时,会使用构造函数中的CancellationToken

因此,如果您使用TaskFactory.StartNew而没有CancellationToken重载

,那么在构造函数中传递'use strict'; const sleep = require('sleep'); const Raspistill = require('node-raspistill').Raspistill; const pixel_getter = require('pixel-getter') const camera = new Raspistill({ verticalFlip: true, horizontalFlip: true, width: 500, height: 500, encoding: 'jpg', noFileSave: true, time: 5 }); function TakePictureLoop() { console.log('taking picture'); camera.takePhoto().then((photo) => { console.log('got photo'); pixel_getter.get(photo, function(err, pixels) { console.log('got pixels'); TakePictureLoop(); }); }); } TakePictureLoop(); 只会很有用