Wie kann ich Variablen mit anonymer Methode erfassen, wenn ich sie in OTL verwende?
Was ich machen will; was ich vorhabe zu tun:
Ich habe ein paar Objekte in einer Genryliste. Ich möchte jedes dieser Objekte in einer anonymen Methode erfassen und diese Methode als separate OTL-Task ausführen.
Dies ist ein vereinfachtes Beispiel:
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.
Und das ist das Ergebnis:
Wie Sie sehen können, scheint das Aufnehmen im Haupt-Thread gut zu funktionieren. Ich weiß jedoch nicht, ob ein Zeiger auf ein Objekt erfasst wurde oder nur sein ID-Feld?
Wenn ich versuche, das Objekt zu erfassen und die anonyme Methode an zu übergebenCreateTask
Funktion Dinge werden seltsam.
Zunächst nur die dritte Instanz vonTMyObject
schien gefangen zu sein. Zweitens habe ich vier Nachrichten im Konsolenprotokoll, obwohl die allgemeine Liste nur drei Objekte enthält. Das zweite Verhalten ist inkonsistent, manchmal habe ich drei Nachrichten in der Konsole, manchmal habe ich vier.
Bitte erläutern Sie mir den Grund für die beiden oben genannten Probleme und schlagen Sie eine Lösung vor, die das Problem beseitigt und es mir ermöglicht, jede Objektinstanz an eine separate OTL-Aufgabe zu übergeben. (Ich möchte nicht regelmäßig verwendenTThread
Klasse.)