C# 4.0 TaskFactory.StartNew<;TResult>;方法(Func<;对象和 ;TResult>;,和 ;对象)
我读了一本关于在MSDN中为多个先行项创建一个延续的书,我很难理解其中的一个示例代码。我正在粘贴下面的代码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));
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在示例中的适用性如何。要实际将参数传递给lamdaStartNew
需要了解它:因此,当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)));
}