![]() |
Form.ShowModal im Thread
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:
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!
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; Was mach ich falsch? Und wie macht man's richtig? Danke :hi: |
Re: Form.ShowModal im Thread
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.
|
Re: Form.ShowModal im Thread
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"? :duck: |
Re: Form.ShowModal im Thread
Siehe
![]() |
Re: Form.ShowModal im Thread
Zitat:
|
Re: Form.ShowModal im Thread
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:
Passt das so?
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. Danke für eure Geduld. :stupid: |
Re: Form.ShowModal im Thread
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 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