ThreadPool.QueueUserWorkItem внутри foreach использует тот же набор данных
В функции ниже всегда одно и то же user
объект передается DoRestCall
метод
(У меня есть вход в DoRestCall
метод, и он имеет те же первые данные в user
объект) Нужно ли использовать Parallel.ForEach вместо Threadpool
private void CreateUser(DataServiceCollection<User> epUsers)
{
foreach (User user in epUsers)
{
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(f =>
{
DoRestCall(string.Format("MESSAGE-TYPE=UserEnrollmentCreate&PAYLOAD={0}",
GenarateRequestUserData(user)), true);
}));
}
catch (Exception ex)
{
_logger.Error("Error in CreateUser " + ex.Message);
}
}
}
1 ответ
Решение
Проблема заключается в том, как обрабатываются переменные цикла, когда они используются в лямбда-выражении или анонимных методах. Лямбда-выражение видит текущее значение переменной цикла во время выполнения лямбда-выражения. Я считаю, что это поведение было изменено в C# 5.0, но еще не пробовал.
Вам нужно сохранить текущего пользователя в переменной внутри цикла foreach и использовать ее вместо переменной цикла (кроме того, ваш try / catch не перехватывает никаких исключений внутри вашего цикла). WaitCallback
см. исправление ниже):
foreach (User user in epUsers)
{
User currentUser = user;
ThreadPool.QueueUserWorkItem(new WaitCallback(f =>
{
try
{
DoRestCall(string.Format("MESSAGE-TYPE=UserEnrollmentCreate&PAYLOAD={0}",
GenarateRequestUserData(currentUser)), true);
}
catch (Exception ex)
{
_logger.Error("Error in CreateUser " + ex.Message);
}
}));
}