考虑一种情况,当方法返回一个任务链时,就像这个(我主要使用.net 3.5,所以示例使用ContinueWith,但await
的问题是相同的):
static Task UnwrappedTask()
{
Task<Task> t = TestStr().ContinueWith( (
return GetTaskFromString(s).ContinueWith(
// returns a task
});
});
return t.Unwrap();
}
static async Task GetTaskFromString(string str)
{
await Task.Delay(3000);
}
static async Task<string> TestStr()
{
await Task.Delay(3000);
return "res";
}
每次从ContinueWith()
返回时是否都创建了一个新的Task对象,或者编译器是否以某种方式重用了该实例?我对Value类型Task.Result在这种情况下的行为感兴趣:它是在那些时候复制的,还是包装器Task类提供了一种将它传输到最外层方法的有效方法?
答案 0 :(得分:3)
ContinueWith
将始终创建新任务。它不可能做任何其他事情。该方法的整个设计是ContinueWith
采用现有的Task
,在完成后执行一些任意方法,并产生新的结果。 ContinueWith
的结果永远不会与它作为延续的任务完全相同,因此它不能仅仅重复使用它。根据设计,它不是变异它正在添加延续的任务(至少以任何外部可见的方式,技术上存储延续到火是任务的内部变异)。