The documentation describes what's happening:
Note that variable capture captures variables—not values. If a variable's value changes after being captured by constructing an anonymous method, the value of the variable the anonymous method captured changes too, because they are the same variable with the same storage.
In your code, there is only one LObject
variable, so all the anonymous methods you construct refer to it. As your loop makes progress, the value of LObject
changes. The tasks haven't gotten a chance to start running yet, so when they do finally run, the loop has terminated and LObject
has its final value. Formally, that final value is undefined after the loop.
To capture the value of the loop variable, wrap creation of the task in a separate function:
function CreateItemTask(Obj: TMyObject): TOmniTaskDelegate;
begin
Result := procedure(const Task: IOmniTask)
begin
Writeln(Format('[Thread %d] Object ID: %d',[Task.UniqueID, Obj.ID]));
end;
end;
Then change your loop code:
CreateTask(CreateItemTask(LObject)).Unobserved.Run;