Ich würde in so einem Fall auch TTask.Run nehmen...
es sei den,
Ich will nicht den Overhead und erzeuge mir vorab einen Thread. Diese kille ich am Ende des Programms.
Der Thread wartet auch einen TEvent und verbraucht keine Taktzyklen, starten aber in wenigen Pico Sekunden.
Dafür erzeuge ich ggf. eine Queue in die ich neue Werte schreibe und der Thread startet, wenn das passiert ist.
Oder halt nur einen Wert. Also Werte an Thread übergeben, SetEvent aufrufen fertig. Wenn der Thread die Arbeit erledigt hat,
legt er sich wieder schlafen...
Oder ich nutze FreeOnTerminate und gebe dem Thread ein Notifyer Interface mit, dass dann die Werte halten kann, wenn der Thread schon
lange tot ist.
Zum Beispiel so:
Delphi-Quellcode:
program Project13;
{$APPTYPE CONSOLE}
uses
System.Classes
, System.SysUtils
, Windows
;
Type
INotify =
Interface
['
{27E27AAC-63A6-4289-8B58-BCD4039AAE6C}']
Procedure Ready(Value : Integer);
End;
TNotify =
Class(TInterfacedObject,INotify)
strict private
Procedure Ready(aValue : Integer);
private
fValue : Integer;
fOnReady : TProc<Integer>;
public
Constructor Create(aProc : TProc<Integer>);
Destructor Destroy;
override;
end;
TWorker =
Class(TThread)
Protected
Procedure Execute;
override;
private
fNotify : INotify;
public
Constructor Create(aNotify : INotify);
End;
{ TNotify }
constructor TNotify.Create(aProc: TProc<Integer>);
begin
Inherited Create;
fOnReady := aProc;
end;
destructor TNotify.Destroy;
begin
fOnReady(fValue);
inherited;
end;
procedure TNotify.Ready(aValue: Integer);
begin
fValue := aValue;
end;
{ TWorker }
constructor TWorker.Create(aNotify: INotify);
begin
fNotify := aNotify;
FreeOnTerminate := true;
inherited Create(false);
end;
procedure TWorker.Execute;
begin
Sleep(5000);
fNotify.Ready(42);
end;
var
Worker : TWorker;
begin
try
Worker := TWorker.Create(TNotify.Create(
Procedure (aValue : Integer)
begin // Still Thread Context
Writeln(aValue,'
MainThread:',Windows.GetCurrentThreadId() = System.MainThreadID);
end));
except
on E:
Exception do
Writeln(E.ClassName, '
: ', E.
Message);
end;
Readln;
end.
Natürlich kann ich daraus auch einen INotify<T> und TWorker<T> machen und das dann für alle möglichen Typen verwenden.
In diesem Fall, würde ich den Execute Teil, ggf. Überschreiben.
Mavarik