根据MSDN:
您可以使用AttachedToParent选项表达结构化任务 并行性,因为父任务隐含地等待所有孩子 完成的任务。
所以我有这段代码:
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。
答案 0 :(得分:5)
使用基于任务的异步模式(TAP)的代码通常不使用AttachedToParent
。 AttachedToParent
是任务并行库(TPL)设计的一部分。 TPL和TAP都共享相同的Task
类型,但在TAP代码中应该避免许多TPL成员。
在TAP中,您可以通过“父”异步方法await
从“子”异步方法返回的任务来支持“父”和“子”异步方法的概念:
public async Task<int> GetIntAsync()
{
var childTask = Task.Run(() =>
{
...
await Task.Delay(1000);
...
});
...
await childTask;
return 1;
}
答案 1 :(得分:4)
AttachedToParent仅附加到计划的任务。您的异步方法返回的任务未安排,而是(隐式)来自TaskCompletionSource
答案 2 :(得分:1)
这是一个适用于动态数量的子任务的解决方案。
一般来说,使用列表是天真的。
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;
}
请注意,这是一个任务的链接列表,一旦任务完成就会收缩。