Параметр считывается при выполнении задачи, а не при объявлении - PullRequest
0 голосов
/ 01 февраля 2012

Я пытаюсь выяснить, как это сделать правильно. Происходит следующее: «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 ]

1 голос
/ 01 февраля 2012

Из того, что я могу сказать о вашем коде, tmpUserObject является экземпляром класса. Это никогда не "оценивается". Лямбда, которую вы передаете задаче (() => Match.UserObject.InitUser(tmpUserObject)), оценивается при запуске задачи, что происходит асинхронно. Это цель объекта 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);
    }
}
1 голос
/ 01 февраля 2012

Это называется замыканием .
Это одна из более мощных функций C #.

Если вы хотите заранее оценить выражение, вы можете поместить его в отдельную переменную внелямбда.

...