请参阅下面的代码摘录,我在此处找到:https://msdn.microsoft.com/en-us/library/dd537612(v=vs.110).aspx:
static void SimpleContinuation()
{
string path = @"C:\users\public\TPLTestFolder\";
try
{
var firstTask = new Task(() => CopyDataIntoTempFolder(path));
var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));
firstTask.Start();
}
catch (AggregateException e)
{
Console.WriteLine(e.Message);
}
}
我对Lambda表达式感到困惑:
var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));
目的是什么:(t)
?为什么它包含在括号中? t没有在任何地方定义。
我已阅读此网页,但未回答我的问题:https://msdn.microsoft.com/en-us/library/bb397687.aspx
答案 0 :(得分:1)
Task.ContinueWith需要一个Action<Task>
- 一个接受Task
作为参数的“方法”。 t
将成为Task
将ContinueWith
提供该方法的参数。
该方法类似于:
void noName(Task t)
{
CreateSummaryFile(path);
}
ContinueWith
然后会在适当的时候执行此匿名方法,为其提供t
(将被忽略),并调用CreateSummaryFile(path)
。
答案 1 :(得分:1)
如果你意识到那里使用的表格有一个简写并且完整形式是:
,那也许会更清楚一点。(Task t) => CreateSummaryFile(path)
它定义了Action<Task>
,因此t is not defined anywhere
的计数器实际上是在那里定义的。
当可以从上下文推断时,你可以省略该类型(就像在这里一样)。当只有一个参数时,你也可以省略括号,所以这也可以是:
t => CreateSummaryFile(path)
现在,t
并未在此处使用,但它经常使用,而且非常有用。更重要的是,在ContinueWith
上调用Task<TResult>
时,t
的类型将为Task<TResult>
,结果可用于后续任务。
有些人喜欢使用_
来表示用于发出信号的参数,我必须在此处输入一个参数,但它没有做任何事情。但是后来有些人也讨厌那种惯例。 YMMV。
答案 2 :(得分:0)
The signature of ContinueWith
is:
Task ContinueWith(Action<Task> continuationAction)
Action<Task>
部分意味着您必须使用一个类型为Task
的输入参数并返回void
来传递委托。也就是说,ContinueWith
将在适当的时间调用该委托并传递Task
类型的参数。
C#中的lamdba表达式是委托的简写。 lambda运算符(=>
)的左边是参数,右边是将要执行的正文。由于您将获得类型为Task
的参数,因此您将需要该类型的参数。在你的情况下是t
。你不需要这个值也没什么区别。您仍然需要声明它以满足lamdba表达式的签名。