![]() |
AW: Anwendung sauber beenden, während Thread läuft
Es ist Fall a). Die Komponente stellt Methoden bereit, um indirekt auf den Thread Einfluss zu nehmen (diese heißen z.B. StopSearch, ContinueSearch, Abort usw.). Die direkte Kommunikation mit dem Thread übernimmt aber die Komponente, da der Thread nach außen gar nicht bekannt ist.
|
AW: Anwendung sauber beenden, während Thread läuft
Ok, wie wäre denn sowas:
Delphi-Quellcode:
type
TMyThreadComponent = class( TComponent ) private FMyThread : TMyThread; FEdit : TEdit; procedure SetEdit( const Value : TEdit ); protected procedure DoEvent( const Info : string ); public constructor Create( AOwner : TComponent ); override; destructor Destroy; override; published property Edit : TEdit read FEdit write SetEdit; end; procedure TMyThreadComponent.DoEvent( const Info : string ); begin if Assigned( Edit ) and ( Self.ComponentState = [] ) then Edit.Text := Info; end; |
AW: Anwendung sauber beenden, während Thread läuft
Nützt mir leider nichts, da ich innerhalb der Komponente weder wissen kann noch will, was am Frontend geschieht, sobald ich ein Event auslöse. Ansonsten hätte ich auch FreeNotification oder sowas in Betracht gezogen.
|
AW: Anwendung sauber beenden, während Thread läuft
Zitat:
|
AW: Anwendung sauber beenden, während Thread läuft
Du hast mein Dilemma erkannt :mrgreen: Ich glaube, ich lasse das jetzt so, dann wird eben in einer README darauf hingewiesen, dass man beim Schließen ggf. noch den Thread anhalten muss. Die Exception tritt sonst evtl. immer noch auf, wird aber ja von mir abgefangen und kommt somit nicht mehr hoch.
|
AW: Anwendung sauber beenden, während Thread läuft
Also ich habe da mal auf die Schnelle zusammengehauen mit dem ComponentState und das funktioniert einwandfrei
Delphi-Quellcode:
Die Komponente hat als Owner das Formular und sobald das Formular in die ewigen Jagdgründe geschickt wird, dann ändert sich erstmal der ComponentState von allen Components, die das Formular als Owner haben. Somit würden also diese Events zwar vom Thread noch aufgerufen aber nicht mehr wirklich bedient.
procedure TMyThreadComponent.DoEvent( const Info : string );
begin if Assigned( Edit ) and ( Self.ComponentState = [] ) then Edit.Text := Info; end; Und
Delphi-Quellcode:
prüft ja auch nicht irgendwas abstruses von ausserhalb ab, sondern den Status deiner eigenen Komponente
( Self.ComponentState = [] )
EDIT Hier mal die gesamte Komponente (ist nicht schön und auch nicht wirklich ThreadSafe abgesichert)
Delphi-Quellcode:
unit uMyThreadComponent;
interface uses Classes, Vcl.StdCtrls; type TMyDoEvent = procedure( const Info : string ) of object; TMyThread = class( TThread ) private FOnDoEvent : TMyDoEvent; procedure SetOnDoEvent( const Value : TMyDoEvent ); protected procedure Execute; override; procedure DoEvent; public property OnDoEvent : TMyDoEvent read FOnDoEvent write SetOnDoEvent; end; TMyThreadComponent = class( TComponent ) private FMyThread : TMyThread; FEdit : TEdit; procedure SetEdit( const Value : TEdit ); protected procedure DoEvent( const Info : string ); public constructor Create( AOwner : TComponent ); override; destructor Destroy; override; published property Edit : TEdit read FEdit write SetEdit; end; implementation uses System.SysUtils; { TMyThreadComponent } constructor TMyThreadComponent.Create( AOwner : TComponent ); begin inherited; FMyThread := TMyThread.Create( True ); FMyThread.OnDoEvent := DoEvent; FMyThread.Start; end; destructor TMyThreadComponent.Destroy; begin FMyThread.Terminate; FMyThread.WaitFor; FMyThread.Free; inherited; end; procedure TMyThreadComponent.DoEvent( const Info : string ); begin if Assigned( Edit ) and ( Self.ComponentState = [] ) then Edit.Text := Info; end; procedure TMyThreadComponent.SetEdit( const Value : TEdit ); begin FEdit := Value; end; { TMyThread } procedure TMyThread.DoEvent; begin if Assigned( OnDoEvent ) then FOnDoEvent( FormatDateTime( 'hh:nn:ss.zzz', now ) ); end; procedure TMyThread.Execute; begin while not Terminated do begin Synchronize( DoEvent ); Sleep( 20 ); end; end; procedure TMyThread.SetOnDoEvent( const Value : TMyDoEvent ); begin FOnDoEvent := Value; end; end. |
AW: Anwendung sauber beenden, während Thread läuft
Du hast mich gerade auf eine Idee gebracht, ich probiere mal etwas aus (mit ComponentState hatte ich auch schon probiert, kann mir aber denken, wo evtl. mein Denkfehler lag).
[edit] Danke für den Schubs in die richtige Richtung. Statt den Thread direkt das Event ausführen zu lassen, benachrichtigt er nun die Komponente, welche zuerst ihren ComponentState prüfen kann und dann das Event auslöst oder eben nicht. So scheint das zu klappen :) [/edit] |
AW: Anwendung sauber beenden, während Thread läuft
Zitat:
|
AW: Anwendung sauber beenden, während Thread läuft
Das wirklich Lustige daran ist ja, dass ich das bei einem Event bereits genau so gemacht hatte. Wieso bei den anderen nicht, das wird wohl für immer ein Geheimnis meines wirren Hirns bleiben :mrgreen: (immer diese Stimmen *huuuu*).
|
AW: Anwendung sauber beenden, während Thread läuft
...oder die Medikamentendosis erhöhen :lol: Es gibt aber noch die Möglichkeit das deine Kaffemaschine kaputt ist... :gruebel:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18: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