Reputation: 505
In the function below always the same user
object is passed to the DoRestCall
method
(I do have logging in the DoRestCall
method and it has the same first data in the user
object)
Do I need to use Parallel.ForEach instead of 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);
}
}
}
Upvotes: 0
Views: 1186
Reputation: 1216
The problem is how loop variables are handled when used in a lambda expression or anonymous methods. The lambda expression sees the current value of the loop variable at the time the lambda is executed. I believe this behaviour was changed in C# 5.0, but haven't tried it yet.
You need to store the current user in a variable inside the foreach loop and use that instead of the loop variable (also, your try / catch doesn't catch any exceptions inside your WaitCallback
, see fix below):
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);
}
}));
}
Upvotes: 3