0

所以我在这里有这个代码:

initialTask.ContinueWith((argument) => { ... });

我知道第二个任务在第一个任务完成后执行。我必须为第二个任务提供一个参数,它也是类型任务。

这个“论点”是旧任务还是一个全新的实例?

例如,当我想在第二个任务中处理第一个任务的取消时,我是否必须调用:

初始任务.IsCanceled

或者

参数.IsCanceled

?

4

2 回答 2

1

这个“论点”是旧任务还是一个全新的实例?

是的,它是对作为参数传递给.ContinueWith(即“旧”)的相同任务实例参数的引用 - 您可以按以下方式验证这一点:

var initialTask = Task.Delay(1000);
initialTask.ContinueWith(t2 => {Debug.Assert(t2 == initialTask);}).Wait();

之所以传入任务实例,是为了让你可以访问Task的完成状态和输出。但是,在访问 的结果之前t2,您需要查看它是否会抛出异常 ( t2.IsFaulted)、取消 ( t2.IsCanceled) 等,这些异常会很快变得混乱。

相反,既然 C# 支持async / await语法,那么您应该会发现代码更易于阅读,并且更易于处理异常等,如果您按如下方式重写代码:

async Task MyMethod()
{
   try
   {
      var initialResult = await SomeInitialTask();
      var secondResult = await SecondTask(initialResult); // instead of .ContinueWith and accessing t2.Result
      ... etc.
   }
   catch (Exception ex)
   {
      // Much easier than checking .IsFaulted on each nested task
   }
}  
于 2020-01-30T11:30:52.610 回答
1

argument是旧任务。它是为了方便和高效而提供的。没有它,lambda 将被迫关闭initialTask外部范围内的变量,并且闭包会产生内存开销

于 2020-01-30T16:53:49.627 回答