![]() |
[Threads] OnTerminate bei Threads in DLLs
Hallo Leute,
bin immernoch an der Thread-Problematik dran. Ich habe grad das Problem, dass die OnTerminate-Methode nicht aufgerufen wird. Hier mal meine Programmstruktur, bevor ich Quelltext poste: Also, ich habe das Hauptprogramm mit der Navigation links. Rechts ist ein großes Panel, in welchem die PlugIns angezeigt werden. Mit Klick auf einen Navigationseintrag wird das entsprechende DLL geladen und im Panel dessen Form angezeigt. Das war's eigentlich schon. Nun habe ich ein Update-Plugin. Es wird auch im Panel angezeigt und es arbeitet auch. Doch Ereignisse aus der DLL-Form, die mit dem Thread verknüpft sind, werden nicht ausgeführt - so auch das OnTerminate-Ereignis nicht. Sogar dann nicht, wenn es im Thread selbst ist. Der Thread an sich ist eine eigenständige Unit. Hier mal Quelltext: - Form1 des Update-Plugins
Delphi-Quellcode:
procedure TForm1.DLFinished(Sender: TObject);
begin ShowMessage('SD'); end; procedure TForm1.PngBitBtn2Click(Sender: TObject); var UpdateSucher: TSeekUpdate; begin UpdateSucher:=TSeekUpdate.Create(true); UpdateSucher.UpdateHost:='http://meinehp.de/Produkte/programmname/updates.ini'; UpdateSucher.VCLForm:=Form1; UpdateSucher.OnTerminate:=DLFinished; UpdateSucher.FreeOnTerminate:=True; UpdateSucher.Resume; end;
Delphi-Quellcode:
Liegt es daran, dass das PlugIn eine DLL ist? Wenn ja, wie kann ich es so umbauen, dass es trotzdem funktioniert?
type
TSeekUpdate = class(TThread) private fHost: String; fVCLForm: TForm; function GetVersion(Filename: string): string; procedure SetUpdateHost(Value: String); procedure SetVCLForm(Value: TForm); procedure Test(Sender: TObject); protected procedure Execute; override; published property UpdateHost: String read fHost write SetUpdateHost; property VCLForm: TForm read fVCLForm write SetVCLForm; end; procedure TSeekUpdate.Test(Sender: TObject); begin MessageBox(VCLForm.Handle, PChar('Hallo'), PChar('hallo'), 0); // Diese Box erscheint auch nicht. end; procedure TSeekUpdate.Execute; var ... begin inherited; Self.OnTerminate:=Test; //das zum Test, da "DLFinishes" in Form1 nicht aufgerufen wurde. end; Danke |
Re: [Threads] OnTerminate bei Threads in DLLs
Zitat:
Wenn TThread in einer DLL benutzt wird funktioniert synchronoize nicht. Und onTerminate wird über synchronize aufgerufen. |
Re: [Threads] OnTerminate bei Threads in DLLs
Hm. Was mache ich dagegen? Muss ich zwangsläufig auf Messages umsteigen?
|
Re: [Threads] OnTerminate bei Threads in DLLs
Sieht so aus.
|
Re: [Threads] OnTerminate bei Threads in DLLs
Oder ich merke mir einfach, dass ich solche Sachen immer außerhalb von DLLs mache. Zum Beispiel im Hauptprogramm - wo's ja eigentlich hingehört.
Die nächsten Probleme kämen ja spätestens bei der Fortschrittsanzeige. Ich könnte demnach ja nie synchronize aufrufen - es bleibt ja immer in der DLL. Btw: Diese Thema hatten wir beide übrigens schonmal. Ist zwar ein bisschen her, aber ich dachte, es gäbe doch einen kleinen Trick, wie das funktionieren könnte. |
Re: [Threads] OnTerminate bei Threads in DLLs
evtl.
![]() Kannst ja mal probieren. Ich weis grad nicht, ob ich damals auch das onTerminate eingebaut hatte. Edit: Sieht so aus, als hät' ich. |
Re: [Threads] OnTerminate bei Threads in DLLs
Das schaue ich mir gleich mal an.
Aber eine Frage noch. Ich habe den Thread von oben jetzt mal in das Hauptprogramm eingebaut. Nun hängt das Programm immer komplett, nachdem der Thread freigegeben worden ist. Egal auf welche Art und Weise. Wieso ist das so? |
Re: [Threads] OnTerminate bei Threads in DLLs
Hast du deine Messagebox weggeklickt?
|
Re: [Threads] OnTerminate bei Threads in DLLs
Ja. Aber auch ohne MessageBox / ShowMessage etc. Hängt der Thread.
Auch bei FreeOnTerminate:=True. |
Re: [Threads] OnTerminate bei Threads in DLLs
Hier nochmal der Quellcode:
Delphi-Quellcode:
Und der Thread
procedure TFOrm1.AfterSeekUpdates(Sender: TObject);
begin ShowMessage('SD'); UpdateSucher.Free; // Hier hängt alles end; procedure TForm1.Button1Click(Sender: TObject); begin UpdateSucher:=TSeekUpdate.Create(True); //UpdateSucher.UpdateHost:='http://www.****.de/Produkte/*****/updates.ini'; UpdateSucher.OnTerminate:=AfterSeekUpdates; UpdateSucher.FreeOnTerminate:=False; UpdateSucher.Resume; end;
Delphi-Quellcode:
type
TSeekUpdate = class(TThread) private fHost: String; fVCLForm: TForm; function GetVersion(Filename: string): string; procedure SetUpdateHost(Value: String); procedure SetVCLForm(Value: TForm); protected procedure Execute; override; published property UpdateHost: String read fHost write SetUpdateHost; property VCLForm: TForm read fVCLForm write SetVCLForm; end; procedure TSeekUpdate.Execute; var www: TIdHttp; memini: TMemInifile; updates, entries: TStrings; i: Integer; filepath: String; inidir: String; inifile: String; iniversion: String; localversion: String; begin inherited; //alles auskommentiert end; |
Re: [Threads] OnTerminate bei Threads in DLLs
Keine Ahnung, was da ist.
Vielleicht die indy-Komponente? |
Re: [Threads] OnTerminate bei Threads in DLLs
Nochmal zurück zu deinem Problem mit dem fehlenden Synchronize in der DLL: Übergebe doch einfach einen Methoden-/Funktionspointer an deinen Thread, der am Ende von Execute aufgerufen wird und schütze dich vor möglichen Konflikten über eine kritische Sektion (TCriticalSection). Mit OnTerminate habe ich selbst auch schon schmerzliche Erfahrungen gemacht. Wann immer möglich sollte man dieses Ereignis vermeiden.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:23 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