TaskFactory.StartNew <tresult>方法(Func <object,tresult>,Object)

时间:2017-04-26 19:11:29

标签: c#-4.0 task-parallel-library

我正在阅读有关在MSDN https://msdn.microsoft.com/en-us/library/ee372288(v=vs.110).aspx中为多个前提创建延续的阅读,并且我很难理解代码,这是他们使用的一个示例。我正在粘贴下面的代码。

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

当我读到StartNew重载时,MSDN states

public Task<TResult> StartNew<TResult>(
  Func<object, TResult> function,
  object state
)

参数

功能

输入:System.Func<Object, TResult>
一个函数委托,它通过Task<TResult>返回将来可用的结果。

状态

输入:System.Object
包含要由函数委托使用的数据的对象。

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

1 个答案:

答案 0 :(得分:2)

什么是Func<object, TResult>?它是一种委托,接受object并返回TResultTResult MethodName(object b)

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

List<Task<int>> tasks

现在您需要调用此方法,因此您传递了第二个参数private int Square(object b) { int i = (int) b; return i * i; } 。因此,对于从baseValue1的每个数字,您可以得到它的平方: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 <= 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))); } 内的委托将被重新创建(感谢@CoryNelson)。

请注意,初始代码是一个示例,不应该用作在生产代码中重现的模式:它使用Task阻止当前执行(只有.Result方法无法&# 39; t为main),它使用asynccan behave unexpectedly

一些有用的链接: