What I want to do:
I have several objects in the list of genres. I want to capture each of these objects with an anonymous method and execute this method as a separate OTL task.
This is a simplified example:
program Project51; {$APPTYPE CONSOLE} uses SysUtils, Generics.Collections, OtlTaskControl, OtlTask; type TProc = reference to procedure; type TMyObject = class(TObject) public ID: Integer; constructor Create(AID: Integer); end; constructor TMyObject.Create(AID: Integer); begin ID := AID; end; var Objects: TList<TMyObject>; LObject: TMyObject; MyProc: TProc; begin Objects := TList<TMyObject>.Create; Objects.Add(TMyObject.Create(1)); Objects.Add(TMyObject.Create(2)); Objects.Add(TMyObject.Create(3)); for LObject in Objects do begin //This seems to work MyProc := procedure begin Writeln(Format('[SameThread] Object ID: %d',[LObject.ID])); end; MyProc; //This doesn't work, sometimes it returns 4 lines in console!? CreateTask( procedure(const Task: IOmniTask) begin Writeln(Format('[Thread %d] Object ID: %d',[Task.UniqueID, LObject.ID])); end ).Unobserved.Run; end; Sleep(500); //Just wait a bit for tasks to finish Readln; end.
And this is the result:

As you can see, the capture seems to work fine in the main thread. However, I do not know if the pointer to the object was captured or only its ID field?
When I try to capture an object and pass an anonymous method to the CreateTask function, things get weird.
First of all, only the third instance of TMyObject seemed to be captured. Secondly, I have four messages in the console log, despite the fact that I have only three objects in the general list. The second behavior is inconsistent, sometimes I have three messages in the console, sometimes I have four.
Please explain to me the cause of the two problems mentioned above and suggest a solution that fixes the problem and allows you to transfer each instance of the object to a separate OTL task. (I do not want to use the regular TThread class.)
Wodzu source share