任务运行时读取参数,而不是在声明时读取

时间:2012-01-31 21:51:50

标签: c#-4.0 task

我正试图找出如何正确地做到这一点。发生的事情是“任务MyTask = new Task(()=> Match.UserObject.InitUser(tmpUserObject));”, tmpUserObject 在任务运行时得到评估,而不是在声明它时。由于这似乎是一个“特性”,因此在声明任务时必须有一种正确的方法来使用tmpUserObject的值。

谢谢: - )

Match.UserObject tmpUserObject;    
while (myReader.Read())
{
    if (tmpDict.TryGetValue(UserID, out tmpUserObject))
    {
        tmpUserObject.vchSchoolID.Add(myReader.GetString(5));
    }
    else
    {
        tmpUserObject = new Match.UserObject();
        //Assign some values from reader...
        //Do any processing eg. DoubleMetaphone pre-computation...etc...
    Task MyTask = new Task(() => Match.UserObject.InitUser(tmpUserObject));
    TaskList.Add(MyTask);
    }
}

//Block until all the tasks are done
Task[] MyTaskArray = TaskList.ToArray();
Task.WaitAll(MyTaskArray);

2 个答案:

答案 0 :(得分:1)

这称为closure 这是C#更强大的功能之一。

如果要提前评估表达式,可以将它放在lambda之外的单独变量中。

答案 1 :(得分:1)

从我所知的代码中,tmpUserObject是一个类实例。永远不会“评估”。传递给任务(() => Match.UserObject.InitUser(tmpUserObject))的lambda在任务运行时进行评估,这确实是异步发生的。这就是Task对象的目的。

当你说“使用tmpUserObject的值”时,你的意思是什么?

编辑:要捕获该值,您需要在每次迭代时将其分配给新变量。您可以通过将变量重新定义为循环内部来实现此目的:

while (myReader.Read())
{
    // Since we moved this inside the loop, the variable's scope has changed.
    Match.UserObject tmpUserObject;    
    if (tmpDict.TryGetValue(UserID, out tmpUserObject))
    {
        tmpUserObject.vchSchoolID.Add(myReader.GetString(5));
    }
    else
    {
        tmpUserObject = new Match.UserObject();
        //Assign some values from reader...
        //Do any processing eg. DoubleMetaphone pre-computation...etc...
        Task MyTask = new Task(() => Match.UserObject.InitUser(tmpUserObject));
        TaskList.Add(MyTask);
    }
}