AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Formular in Thread auslagern

Ein Thema von Gruber_Hans_12345 · begonnen am 3. Feb 2014 · letzter Beitrag vom 3. Feb 2014
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Formular in Thread auslagern

  Alt 3. Feb 2014, 12:19
Mal so ein kleiner Minimalcode:
Delphi-Quellcode:
var
  LForm : TForm;
  LThread : TThread;
begin
  LForm := TSplashScreen.Create( nil );
  try
    
    LThread := TStartupThread.Create( LForm );
    try

      LForm.ShowModel;
      LThread.WaitFor;

    finally
      LThread.Free;
    end;

  finally
    LForm.Free;
  end;
end;
TStartupThread muss lediglich am Ende eine Nachricht an die Form schicken, damit die geschlossen wird.
Alles weitere (Progress, Infos, ...) ist Zuckerguss und funktioniert auf die gleiche/ähnliche Art.

Das Erzeugen von VCL-Gedöns ausserhalb des MainThread-Context sollte man aber bleiben lassen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.378 Beiträge
 
Delphi 12 Athens
 
#2

AW: Formular in Thread auslagern

  Alt 3. Feb 2014, 12:49
ShowModal?
Bis zum WaitFor kommt der dann ja nicht, falls nicht jemand vorher das Fenster schließt.

Wäre es da nicht andersrum besser?
Delphi-Quellcode:
var
  LForm : TForm;
  LThread : TThread;
begin
  LForm := TSplashScreen.Create(nil);
  try
    LThread := TStartupThread.Create(LForm);
    try
      LForm.Show;
      LThread.WaitFor;
      LForm.Hide;
    finally
      LThread.Free;
    end;
  finally
    LForm.Free;
  end;
end;

// oder

var
  LForm : TForm;
  LThread : TThread;
begin
  LThread := TStartupThread.Create;
  try
    LForm := TSplashScreen.Create(nil);
    try
      LForm.Show;
      LThread.WaitFor;
    finally
      LForm.Free;
    end;
  finally
    LThread.Free;
  end;
end;

Wie schon erwähnt, müssen die VCL-Komponenten im Hauptthread VCL-Thread bleiben.

Man könnte zwar in anderen Threads direkt via WinAPI Formulare nzeigen, aber diese müssen dann komplett in dem Thread erstellt, behandelt und freigegeben werden, inkl. eigener Message-Loop.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 3. Feb 2014 um 12:52 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Formular in Thread auslagern

  Alt 3. Feb 2014, 13:29
ShowModal?
Bis zum WaitFor kommt der dann ja nicht, falls nicht jemand vorher das Fenster schließt.

Wäre es da nicht andersrum besser?
Delphi-Quellcode:
var
  LForm : TForm;
  LThread : TThread;
begin
  LForm := TSplashScreen.Create(nil);
  try
    LThread := TStartupThread.Create(LForm);
    try
      LForm.Show;
      LThread.WaitFor;
      LForm.Hide;
    finally
      LThread.Free;
    end;
  finally
    LForm.Free;
  end;
end;

// oder

var
  LForm : TForm;
  LThread : TThread;
begin
  LThread := TStartupThread.Create;
  try
    LForm := TSplashScreen.Create(nil);
    try
      LForm.Show;
      LThread.WaitFor;
    finally
      LForm.Free;
    end;
  finally
    LThread.Free;
  end;
end;

Wie schon erwähnt, müssen die VCL-Komponenten im Hauptthread VCL-Thread bleiben.

Man könnte zwar in anderen Threads direkt via WinAPI Formulare nzeigen, aber diese müssen dann komplett in dem Thread erstellt, behandelt und freigegeben werden, inkl. eigener Message-Loop.
Bei deiner Variante wird der MainThread aber blockiert
Delphi-Quellcode:
LForm.Show;
// Wir befinden uns im MainThread-Context und da tut sich jetzt nichts mehr, bis der Thread abgearbeitet ist
LThread.WaitFor;
und das ist bei meiner Variante eben genau nicht der Fall.

TStartupThread muss lediglich am Ende eine Nachricht an die Form schicken, damit die geschlossen wird.
Hier mal so ein Beispiel StartupThread
Delphi-Quellcode:
unit StartupThread;

interface

uses
  FormThreadWait,
  System.SysUtils,
  Classes;

type
  TStartupThread = class( TThread )
  private
    FCloseForm : TThreadProcedure;
    FInfoToForm : TProc<string>;
    procedure InfoToForm( const AInfo : string );
  protected
    procedure DoExecute; virtual;
    procedure Execute; override;
  public
    constructor Create( AForm : TThreadWaitForm );
  end;

implementation

{ TStartupThread }

constructor TStartupThread.Create( AForm : TThreadWaitForm );
begin
  inherited Create( False );
  // Anonyme Methode zum Schließen der Form
  FCloseForm := procedure
    begin
      AForm.Close;
    end;
  FInfoToForm := procedure( AInfo : string )
    begin
      AForm.Label1.Caption := AInfo;
    end;
end;

procedure TStartupThread.DoExecute;
var
  LIdx : Integer;
begin
  InfoToForm( 'Initialisierung...' );
  Sleep( 500 );
  for LIdx := 1 to 20 do
  begin
    InfoToForm( 'Schritt ' + IntToStr( LIdx ) );
    Sleep( 250 );
  end;
end;

procedure TStartupThread.Execute;
begin
  inherited;
  try
    DoExecute;
  finally
    // Form schließen synchronisiert abschicken
    // Queue würde auch gehen, aber was sollen wir in der Zwischenzeit noch machen, wir sind fertig ;o)
    Synchronize( FCloseForm );
  end;
end;

procedure TStartupThread.InfoToForm( const AInfo : string );
begin
  Queue(
      procedure
    begin
      FInfoToForm( AInfo );
    end );
end;

end.
Anwendung im Anhang (kompiliert und als Source)
Angehängte Dateien
Dateityp: zip dp_178908.zip (809,1 KB, 44x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz