Thema: Delphi Freigabe Thread

Einzelnen Beitrag anzeigen

Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#22

AW: Freigabe Thread

  Alt 12. Feb 2021, 17:37
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
  Mit Zitat antworten Zitat