Scenario: An asynchronous task in a loop executes a method containing arguments that change as the program continues:
while(this._variable < 100)
{
th
Closures close over variables, not values. Therefore, incrementing _variable
can alter the behavior of the task that refers to it.
You can prevent this by making a local copy:
while (this._variable < 100)
{
this._variable++;
int local = _variable;
var aTask = Task.Factory.StartNew(() =>
{
aList.add(local);
update(this._savePoint);
});
}
Or you could pass the value to the task as state:
while (this._variable < 100)
{
this._variable++;
var aTask = Task.Factory.StartNew(object state =>
{
aList.add((int)state);
update(this._savePoint);
}, this._variable);
}
These both work by copying the value of _variable
to a new temporary variable. In the first case the local
variable 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 _variable
when you pass it to the Task as the state
argument. If _variable
were a reference type, these solutions wouldn't work; you'd have to perform a clone.