AGB  ·  Datenschutz  ·  Impressum  







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

Form.ShowModal im Thread

Ein Thema von gmc616 · begonnen am 6. Dez 2007 · letzter Beitrag vom 7. Dez 2007
Antwort Antwort
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#1

Form.ShowModal im Thread

  Alt 6. Dez 2007, 00:24
Guten Abend DP,

ich fange an mich mit Threads zu beschäftigen. Die ersten paar Threads hab ich auch schon erfolgreich hin gekriegt. So werden in meinem MP3-Player die ID3-Tags in einem Thread ausgelesen und in ein Listview geschrieben. Ob das ganze thread-safe ist weiß ich nicht, aber es funktioniert prima.

Nun möchte ich einen Schritt weiter gehen, und zwar ein Suche-Dialog in einem Thread laufen lassen.

Hintergrund: Auf meinem Hauptfenster wird über einen Timer eine Animation berechnet und dargestellt.
Wenn ich in meinem Suche-Dialog eine Suche starte, animiert meine Animation nicht mehr, da das Suchen die Anwendung blockiert. Klar könnte ich ein ProgressMessages in meine Suche-Funktion einbauen, ist aber nicht Ziel der Sache.

Nun hab ich mir diese Konstruktion in einem Test-Programm zusammen gebastelt.

Delphi-Quellcode:
Type TMyDlgThread = class (TThread)
  private
    FDlg : TMySearchDlg;
    FModalResult : TModalResult;
  public
    Constructor Create(CreateSuspended: Boolean); overload;
    Destructor Destroy (); overload;

    function ShowDlg () : TModalResult;

  protected
    procedure Execute; override;
  end;


constructor TMyDlgThread.Create(CreateSuspended: Boolean);
begin
  inherited;
  self.FreeOnTerminate := false;
  FDlg := TMySearchDlg.Create(nil);
end;

destructor TMyDlgThread.Destroy;
begin
  FDlg.Free;
  inherited;
end;

procedure TMyDlgThread.Execute;
begin
  inherited;
  FModalResult := FDlg.ShowModal;
end;

function TMyDlgThread.ShowDlg: TModalResult;
begin
  Resume;
  WaitFor;
  Result := FmodalResult;
end;
Das ganze endet so, dass mein Suche-Dialog angezeigt wird und dann das ganze Programm stehen bleibt. Nichts geht mehr. Einfach tot, ohne Fehlermeldung und ohne CPU-Last. Nichts!

Was mach ich falsch? Und wie macht man's richtig?

Danke
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Form.ShowModal im Thread

  Alt 6. Dez 2007, 06:02
Alles was mit GUI-Dialogen/Komponenten zu tun hat muss im Hauptthread laufen. Wenn du auf eine Listview zugreifst ohne zu synchonisieren und es läuft hast du zufälligerweise Glück gehabt. Irgendwann wird es auch hier krachen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Form.ShowModal im Thread

  Alt 6. Dez 2007, 11:34
Aha. Naja, das muss man natürlich wissen.

Also packt ich nur die Suche-Funktion in ein Thread.

Und wie synchronisiert man das ganze mit einer Listview z.B.?
Was versteht man unter "Thread synchronisieren"?
  Mit Zitat antworten Zitat
Benutzerbild von Alien426
Alien426

Registriert seit: 21. Dez 2005
146 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Form.ShowModal im Thread

  Alt 6. Dez 2007, 11:41
Siehe Tutorial.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Form.ShowModal im Thread

  Alt 6. Dez 2007, 12:35
Zitat von gmc616:
Aha. Naja, das muss man natürlich wissen.
Wenn du die Unit mit der Thread-Klasse über "Datei/Neu" anlegst schreibt dir Delphi genau diese Probleme + Umschiffung in die Unit als Kommentar hinein.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#6

Re: Form.ShowModal im Thread

  Alt 7. Dez 2007, 12:36
Hallo,

da ja meine eigentliche Frage beantwortet ist, hätte ich noch eine weitere, eine Letzte, Off-Topic sozusagen.

Ich hab mal 'n Stück zusammen geschrieben und möchte eigentlich nur noch wissen, ob dieser so korrekt ist.
Wenn ja, dann glaube ich das Thema Threads und Synchronisation im Grunde verstanden zu haben und es wird Zeit sich sinnvollen Aufagen für Threads zu widmen.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Lv: TListView;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }

  end;

type TMyThread = class (TThread)
  Private
    FsCap, FsSub1, FsSub2 : string;
    FLv : TListView;
    procedure UpdateListView();
    procedure AddLvItem (ACap,ASub1,ASub2 : string);
  protected
    Procedure Execute (); Override;
  public
    Constructor Create (ALv : TListView);
end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var MyThread : TMyThread;
begin
  MyThread := TMyThread.Create(Lv);
end;

{ TMyThread }

constructor TMyThread.Create(ALv : TListView);
begin
  FreeOnTerminate := false;
  Flv := ALv;
  inherited Create (false);
end;

procedure TMyThread.Execute;
var
  i : integer;
begin
  inherited;

  for i:=0 to 9 do
  begin
    FsCap := 'Cap - ' + inttostr (i);
    FsSub1 := 'Sub1 - ' + inttostr (i);
    FsSub2 := 'Sub2 - ' + inttostr (i);
    Synchronize(UpdateListView);
  end;

  Terminate;
end;

procedure TMyThread.UpdateListView;
begin
  AddLvItem(FsCap,FsSub1,FsSub2);
end;

procedure TMyThread.AddLvItem(ACap, ASub1, ASub2: string);
var
  li : TListItem;
begin
  li := Flv.Items.Add;
  li.Caption := ACap;
  li.SubItems.Add(ASub1);
  li.SubItems.Add(ASub2);

end;

end.
Passt das so?

Danke für eure Geduld.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Form.ShowModal im Thread

  Alt 7. Dez 2007, 12:42
Bis auf, dass das Object MyThread nie gelöscht werden kann, da du die Referenz wegschmeisst, ist es ok.
Und terminate solltest du im Thread nicht aufrufen. Terminate wird von außen aufgerufen. Und in einer langen Schleife im Thread solltest du regelmäßig via terminated abfragen ob von außen ein terminate gesetzt wurde und ggf. dann die Schleife abbrechen.

Und du kannst auch (ist kein Fehler, aber ich weis nicht, ob du es bewusst gemacht hast) AddLVItem weglassen und alles in UpdateListview machen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  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 11:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz