TaskCreationOptions.attachedtopparent没有等待子任务

本文关键字:等待 子任务 attachedtopparent TaskCreationOptions | 更新日期: 2023-09-27 17:50:32

根据MSDN:

您可以使用attachedtopparent选项来表示结构化任务并行性,因为父任务隐式地等待所有子任务要完成的任务

我有这样的代码:

public async Task<int> GetIntAsync()
{
    var childTask = Task.Factory.StartNew(async () =>
    {
        await Task.Delay(1000);
    },TaskCreationOptions.AttachedToParent);
    return 1;
}
public async Task<ActionResult> Index()
{
    var watch = Stopwatch.StartNew();
    var task = GetIntAsync();
    var result = await task;
    var time = watch.ElapsedMilliseconds;
    return View();  
}

我想知道为什么时间是0而不是1000

TaskCreationOptions.attachedtopparent没有等待子任务

使用基于任务的异步模式(TAP)的代码通常不使用AttachedToParentAttachedToParent是任务并行库(TPL)设计的一部分。TPL和TAP共享相同的Task类型,但在TAP代码中应该避免许多TPL成员。

在TAP中,您可以支持"parent"answers";child"通过使用"parent"async方法await从子进程返回的任务;异步方法:

public async Task<int> GetIntAsync()
{
  var childTask = Task.Run(async () =>
  {
    ...
    await Task.Delay(1000);
    ...
  });
  ...
  await childTask;
  return 1;
}

attachedtopparent仅附加到已调度的任务。async方法返回的Task不是预定的,而是(隐式地)来自TaskCompletionSource

这个解决方案适用于动态数量的子任务。

一般来说,使用列表是幼稚的。

public async Task<int> GetIntAsync()
{
    var childTasks = new List<Task>();
    while (...)
    {
        ...
        childTasks.Add(Task.Run(...));
        ...
    }
    await Task.WhenAll(childTasks);
    return 1;
}

例如,如果子任务的生存期很短,而新任务的创建速度很快且不受限制,则列表将溢出。

相反,我们可以只使用一个任务。

public async Task<int> GetIntAsync()
{
    var childrenTask = Task.WhenAll();
    while (...)
    {
        ...
        childrenTask = Task.WhenAll(Task.Run(...), childrenTask);
        ...
    }
    await childrenTask;
    return 1;
}

注意,这是一个任务链表,它会在任务完成后立即缩小。