Passing arguments with changing values to Task — Behaviour?

前端 未结 1 1887
无人共我
无人共我 2020-12-30 00:41

Scenario: An asynchronous task in a loop executes a method containing arguments that change as the program continues:

while(this._variable < 100)
{
    th         


        
相关标签:
1条回答
  • 2020-12-30 00:54

    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.

    0 讨论(0)
提交回复
热议问题