![]() |
Warten auf Thread Ende
Hallo Leute
Ich hätte mal eine Frage zum Thread-Design und dem Warten auf das Ende eines Threads. Mit Threads in Delphi stehe ich mehr oder weniger immer auf Kriegsfuß:? Um während einer Wartezeit (z.B. auf einen Download) eine Animation sehen zu können, lasse ich mir in einem Image eine Gif-Animation anzeigen. Der Download selbst wird in einem Thread ausgeführt. Die Animation wird mit folgendem Code angezeigt... {Unit1}
Delphi-Quellcode:
private
FBusyAnimation : Boolean; procedure SetBusyAnimation(Value: Boolean); public property BusyAnimation: Boolean read FBusyAnimation write SetBusyAnimation; end;
Delphi-Quellcode:
procedure TXMFS.FormCreate(Sender: TObject);
begin (Image2.Picture.Graphic as TGIFImage).Animate := True; (Image2.Picture.Graphic as TGIFImage).AnimationSpeed := 210; end;
Delphi-Quellcode:
procedure TXMFS.SetBusyAnimation(Value: Boolean);
begin FBusyAnimation := Value; if FBusyAnimation then Image2.Visible := True else Image2.Visible := False; end; Den Thread erzeuge ich bspw. so... {Unit1}
Delphi-Quellcode:
SetBusyAnimation(True);
TGMD := TThreadGetMBData.Create('artist', 'artist', XMFS.Edit1.Text, '5', True); TGMD.FreeOnTerminate := True; TGMD.Start; Thread... {Unit2}
Delphi-Quellcode:
TThreadGetMBData = class(TThread)
private FTyp: String; FQuery: String; FInput: String; FLimit: String; FShow: Boolean; procedure NotifyEndOfThread; procedure GetMBData(Typ, Query, Input, Limit: String); protected procedure Execute; override; public constructor Create(const ATyp, AQuery, AInput, ALimit: String; AShow: Boolean); end;
Delphi-Quellcode:
GetMbData lädt dann die entsprechende Datei herunter
constructor TThreadGetMBData.Create(const ATyp, AQuery, AInput, ALimit: String; AShow: Boolean);
begin inherited Create(True); FTyp := ATyp; FQuery := AQuery; FInput := AInput; FLimit := ALimit; FShow := AShow; end;
Delphi-Quellcode:
procedure TThreadGetMBData.Execute;
begin CoInitialize(nil); try GetMBData(FTyp, FQuery, FInput, FLimit); finally Synchronize(NotifyEndOfThread); end; end; Hier wird nach Thread-Ende die Animation versteckt und xml-Daten ausgelesen
Delphi-Quellcode:
procedure TThreadGetMBData.NotifyEndOfThread;
begin XMFS.BusyAnimation := False; if FTyp = 'artist' then Mb.ReadArtistData(FShow); if FTyp = 'release-group' then Mb.ReadReleaseGroupData(FShow); end; Ist der Thread und dessen Aufruf so in Ordnung? Ab und zu kann es nun allerdings vorkommen, das ich nach dem Erzeugen des Threads auf seine Fertigstellung warten muss. Ach wenn ich den Sinn und Zweck eines Threads damit wieder zunichte mache. Letztenendes geht es eigentlich nur um die Animation. Hierzu hatte ich nach dem Create ein "FreeOnTerminate := False" und "WaitFor" verwendet, was jedoch nicht wie gewünscht funktionierte. Muss ich stattdessen WaitForSingleObject verwenden? Oder ein Flag bzw. ein Event? Bin für jeden Hinweis dankbar, da dies quasi meine ersten Gehversuche mit Threads sind. Schöne Grüße 4lb3rtO |
AW: Warten auf Thread Ende
Zitat:
![]() Zitat:
|
AW: Warten auf Thread Ende
Zitat:
Stimmt. Das ist ja noch wesentlich geschickter. Hier muss man ja keine Progressbar o.ä. mit dem Hauptthread synchronisieren. Danke für den Tip :thumb: |
AW: Warten auf Thread Ende
Delphi-Quellcode:
Wäre das nicht einfacher oder übersehe ich jetzt was?
procedure TXMFS.SetBusyAnimation(Value: Boolean);
begin FBusyAnimation := Value; Image2.Visible := Value; end; |
AW: Warten auf Thread Ende
Vielen Dank für die zahlreichen Hinweise und Tipps :thumb: Ich habe nun einmal die angesprochenen Änderungen eingefügt. Die read-property und die Variable habe ich entfernt, da sie im späteren Verlauf auch nicht benötigt wird.
Leider funktioniert hier bei der DP kein Line-Highlighting (gelöschte Zeilen rot, neue Zeilen grün markieren/hinterlegen) um die Änderungen besser sichtbar zu machen :( Hier einmal der aktuelle Quelltext. Die Animation wird mit folgendem Code angezeigt... {Unit1}
Delphi-Quellcode:
private
procedure SetBusyAnimation(Value: Boolean); public property BusyAnimation: Boolean write SetBusyAnimation; end;
Delphi-Quellcode:
procedure TXMFS.FormCreate(Sender: TObject);
begin (Image2.Picture.Graphic as TGIFImage).Animate := True; (Image2.Picture.Graphic as TGIFImage).AnimationSpeed := 210; end;
Delphi-Quellcode:
procedure TXMFS.SetBusyAnimation(Value: Boolean);
begin Image2.Visible := Value; end; Den Thread erzeuge ich bspw. so... {Unit1}
Delphi-Quellcode:
TGMD := TThreadGetMBData.Create('artist', 'artist', XMFS.Edit1.Text, '5', True);
TGMD.FreeOnTerminate := True; TGMD.Start; Thread... {Unit2}
Delphi-Quellcode:
TThreadGetMBData = class(TThread)
private FTyp: String; FQuery: String; FInput: String; FLimit: String; FShow: Boolean; procedure NotifyEndOfThread(Sender: TObject); procedure GetMBData(Typ, Query, Input, Limit: String); protected procedure Execute; override; public constructor Create(const ATyp, AQuery, AInput, ALimit: String; AShow: Boolean); end;
Delphi-Quellcode:
GetMbData lädt dann die entsprechende Datei herunter
constructor TThreadGetMBData.Create(const ATyp, AQuery, AInput, ALimit: String; AShow: Boolean);
begin inherited Create(True); XMFS.BusyAnimation := True; FTyp := ATyp; FQuery := AQuery; FInput := AInput; FLimit := ALimit; FShow := AShow; end;
Delphi-Quellcode:
Hier wird nach Thread-Ende die xml-Daten ausgelesen und die Animation versteckt
procedure TThreadGetMBData.Execute;
begin CoInitialize(nil); GetMBData(FTyp, FQuery, FInput, FLimit); OnTerminate := NotifyEndOfThread; end;
Delphi-Quellcode:
procedure TThreadGetMBData.NotifyEndOfThread(Sender: TObject);
begin if FTyp = 'artist' then Mb.ReadArtistData(FShow); if FTyp = 'release-group' then Mb.ReadReleaseGroupData(FShow); XMFS.BusyAnimation := False; end; Jetzt müsste ich nur noch bei Bedarf auf die Fertigstellung des Threads warten können, dann wäre es perfekt. Ich glaube ich habe auch mich im ersten Post in der Beziehung etwas missverständlich ausgedrückt. Im Hauptthread müsste ich nach der Erzeugung des Nebenthreads die Möglichkeit haben, auf dessen Fertigstellung zu warten. Vielleicht auch den Status des Threads abfragen, ob ein Fehler aufgetreten ist?! Wenn man nun bspw. den Thread wie folgt erzeugt, funktioniert die Animation aufgrund des "WaitFor" und des "Free" nicht mehr
Delphi-Quellcode:
TGMD := TThreadGetMBData.Create('artist', 'artist', XMFS.Edit1.Text, '5', True);
TGMD.FreeOnTerminate := False; TGMD.Start; TGMD.WaitFor; // Mach noch etwas TGMD.Free; Was für Möglichkeiten hätte man alternativ um dort eine Pause einzulegen, ohne den Hauptthread einzufrieren und die Animation anzuzeigen? Änderungsvorschläge und Kritik sind nach wie vor erwünscht:wink: Das blöde an der Geschichte ist, das es mehrere solcher Threads gibt und sich das durch das gesamte Programm zieht... Vielen Dank bis dato |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:42 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