Scenario: An asynchronous task in a loop executes a method containing arguments that change as the program continues:
while(this._variable < 100)
{
this._variable++;
var aTask = Task.Factory.StartNew(() =>
{
aList.add(this._variable);
update(this._savePoint);
});
}
If the loop runs faster than the tasks complete, will the list add the current value of the variable or is the variable saved locally and the original value added?
Closures close over variables, not values. Therefore, incrementing
_variablecan alter the behavior of the task that refers to it.You can prevent this by making a local copy:
Or you could pass the value to the task as state:
These both work by copying the value of
_variableto a new temporary variable. In the first case thelocalvariable is defined inside the scope of the loop, so you get a new one for every iteration. In the second case, you make a copy of the value of_variablewhen you pass it to the Task as thestateargument. If_variablewere a reference type, these solutions wouldn’t work; you’d have to perform a clone.