异步任务方法的TaskCreationOptions

use*_*000 3 .net task task-parallel-library async-await c#-5.0

我有一个返回异步任务的方法.我想调用它,但我想自定义发送给它的TaskCreationOptions,我正在尝试为此制定最佳实践,或者我应该如何修改我的方法?

样品..

void Main(){        
    _runTask=Test(); // I wish to provide creation options here, ie LongRunning, and possibly also a cancellation token
}
async Task Test()
{
    await Task.Delay(10);
}
Run Code Online (Sandbox Code Playgroud)

nos*_*tio 6

我希望在这里提供创建选项,即LongRunning,也可能是取消令牌

您无法自定义方法返回TaskCreationOptions的Task对象async.从本质上讲,它没有意义:你不在Task这里创建初始,Task.Delay是的.你可以这样想:

Task Test()
{
    var scheduler = SynchronizationContext.Current != null ?
        TaskScheduler.FromCurrentSynchronizationContext() :
        TaskScheduler.Current;

    return Task.Delay(10).ContinueWith((t) => { }, 
        CancellationToken.None,
        TaskContinuationOptions.None, scheduler);
}
Run Code Online (Sandbox Code Playgroud)

现在,可以控制(包括)TaskContinuationOptions返回的任务,但不能.ContinueWithTaskContinuationOptions.LongRunningTaskCreationOptions

但是,您可以提供取消令牌:

async Task Test(CancellationToken token)
{
    await Task.Delay(10, token);
    // ...
    token.ThrowIfCancellationRequested();
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*ary 5

你不能,也不需要.这些选项都不符合您的想法.

LongRunning对async工作负载没用; 它会(在当前实现中)启动一个单独的专用线程只是为了执行方法的第一部分async(直到第await一个不完整的操作),然后恢复该async方法作为常规工作排队到线程池,忽略该专用该方法其余部分的线程.

传递CancellationToken给任务构造函数是不必要的; 它会让你在async代码中获得的唯一好处是,如果令牌已被取消,代码将无法启动.你可以在调用async方法之前自己检查一下,做同样的事情.基于任务的异步模式文档中async描述了使用方法处理取消的正确方法:

async Task TestAsync(CancellationToken cancellationToken)
{
  await Task.Delay(10, cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)