我正试图找出如何正确地做到这一点。发生的事情是“任务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);
答案 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);
}
}