C# 4.0 TaskFactory.StartNew<;TResult>;方法(Func<;对象和 ;TResult>;,和 ;对象)

C# 4.0 TaskFactory.StartNew<;TResult>;方法(Func<;对象和 ;TResult>;,和 ;对象),c#-4.0,task-parallel-library,C# 4.0,Task Parallel Library,我读了一本关于在MSDN中为多个先行项创建一个延续的书,我很难理解其中的一个示例代码。我正在粘贴下面的代码 for (int ctr = 1; ctr <= 10; ctr++) { int baseValue = ctr; tasks.Add(Task.Factory.StartNew( (b) => { int i = (int) b; return i * i; }, baseValue));

我读了一本关于在MSDN中为多个先行项创建一个延续的书,我很难理解其中的一个示例代码。我正在粘贴下面的代码

for (int ctr = 1; ctr <= 10; ctr++) {
    int baseValue = ctr;
    tasks.Add(Task.Factory.StartNew( (b) =>
      {
        int i = (int) b;
        return i * i;
      },
      baseValue));
}
参数

作用

类型:
System.Func

返回通过
任务可用的未来结果的函数委托

陈述

类型:
System.Object

包含函数委托使用的数据的对象

具体来说,在他们的示例中,当
b
作为
对象传递给函数时,我不理解
baseValue
的用法。

什么是
Func
?它是一种委托类型,它接受
对象
并返回
TResult
TResult方法名(对象b)

在代码示例中,该方法使用内联lambda构造,它接受
对象b
并返回
int
(您可以看到将返回
int
-
列表任务的任务列表):

现在需要调用此方法,因此要传递第二个参数,
baseValue
。因此,对于从
1
10
的每个数字,你得到它的平方:
1+4+9+16+25+36+49+64+81+100
,然后将它们相加,得到
385

因此,整个代码可以理解为:

for (int ctr = 1; ctr <= 10; ctr++)
{
    resultList.Add(Square(ctr));
}
for(int-ctr=1;ctr-Square(baseValue));
}
但是在本例中,您将得到一个闭包,因此与没有闭包的初始变量相比,
任务中的委托每次都将被重新创建(感谢@CoryNelson)

请注意,初始代码是一个示例,不应用作在生产代码中复制的模式:它使用
.Result
阻止当前的执行(只有当
main
方法不能是
async
时才可以),并且它使用
StartNew
,这将导致

一些有用的链接:

  • (C#编程指南)
  • (来自docs.microsoft.com)

baseValue
是一个状态对象,它被传递给提供给
StartNew
的委托。在本例中,
baseValue
将在循环执行时取
ctr
的值。b代表什么?b是传递给lamda的参数,它大致相当于
void SomeFunc(int b)
。请原谅我的愚蠢问题,baseValue在示例中的适用性如何。要实际将参数传递给lamda
StartNew
需要了解它:因此,当lamda执行
b
时,您将要传递给lamda的任何参数传递到
StartNew
中。我要补充一下原因与捕获lambda相比,您可以使用重载,即捕获每次分配一个新的委托,而非捕获的委托只分配一次。@CoryNelson也表示感谢。似乎lambda的概念在我脑海中并不清楚。我希望看到,
for(intctr=1;ctr{inti=(int)b;returni*I;});}Lambda是一个方法定义。定义方法后,需要使用参数调用它,在您的示例中,它是
baseValue
。在您的代码中,您没有提供参数值,因此代码不会编译。注释中的代码示例不会编译您是正确的,我只是想分享我脑海中的想法。lambda运算符左边的b是什么,我认为这是输入,委托方法需要运行,但有人设置了b的值,这是通过baseValue实现的。谁叫这种方法
private int Square(object b)
{
    int i = (int) b;
    return i * i;
}
for (int ctr = 1; ctr <= 10; ctr++)
{
    resultList.Add(Square(ctr));
}
for (int ctr = 1; ctr <= 10; ctr++)
{
    // get a local copy of ctr
    var baseValue = ctr;
    // create a task which will get the square
    tasks.Add(Task.Run(() => baseValue * baseValue));
    // or with a method introduction
    tasks.Add(Task.Run(() => Square(baseValue)));
}