Thema: Delphi Freigabe Thread

Einzelnen Beitrag anzeigen

TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: Freigabe Thread

  Alt 12. Feb 2021, 12:24
So eher nicht:

Code:
Unit1.TAnalyseThread.Destroy
System.TObject.Free
Unit1.TForm1.OnAnalyseReady($2E7DDC0)
Unit1.TAnalyseThread.Execute
System.Classes.ThreadProc($2E7DDC0)
System.ThreadWrapper($2E4A4A0)
:7749fa29 KERNEL32.BaseThreadInitThunk + 0x19
:775e76b4 ntdll.RtlGetAppContainerNamedObjectPath + 0xe4
:775e7684 ntdll.RtlGetAppContainerNamedObjectPath + 0xb4
Erzeugen im Mainthread und im TAnalyseThread-Kontext freigeben ist halt eher ungünstig!

Biete folgende Lösung an:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TAnalyseThread = class(TThread)
  private
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean);
    destructor Destroy; override;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    AnalyseThread: TAnalyseThread;

    procedure OnAnalyseReady(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(AnalyseThread) then
  begin
    FreeAndNil(AnalyseThread);
  end;

  AnalyseThread := TAnalyseThread.Create(True);

  if Assigned(AnalyseThread) then
  begin
    // neu, jetzt noch besser!
    AnalyseThread.OnTerminate := OnAnalyseReady;

    AnalyseThread.Start;
  end;
end;

procedure TForm1.OnAnalyseReady(Sender: TObject);
begin
  // Auswertung des Daten...

  if Assigned(AnalyseThread) then
  begin
    // Wir sind mit allen durch, aber können hier noch nicht freigeben, weil wir noch zu sehr im Sumpf
    // des Synchronize drin sind (siehe procedure TThread.DoTerminate;). Darum noch ne Extra-Runde durch
    // die Windows-Botschaftsbehandlung durch TThread.ForceQueue
    TThread.ForceQueue(nil,
      procedure
      begin
        FreeAndNil(AnalyseThread);
      end);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned(AnalyseThread) then
  begin
    FreeAndNil(AnalyseThread);
  end;
end;

{ TAnalyseThread }

constructor TAnalyseThread.Create(CreateSuspended: Boolean);
begin
  FreeOnTerminate := False;
  inherited Create(CreateSuspended);
  TThread.NameThreadForDebugging('TAnalyseThread', Self.ThreadID);
end;

destructor TAnalyseThread.Destroy;
begin
  inherited Destroy;
end;

procedure TAnalyseThread.Execute;
begin
  // Tue irgendwas bis fertig...
end;

end.

Geändert von TiGü (12. Feb 2021 um 12:26 Uhr)
  Mit Zitat antworten Zitat