Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#16

AW: Anwendung sauber beenden, während Thread läuft

  Alt 3. Feb 2012, 13:56
Also ich habe da mal auf die Schnelle zusammengehauen mit dem ComponentState und das funktioniert einwandfrei
Delphi-Quellcode:
procedure TMyThreadComponent.DoEvent( const Info : string );
begin
  if Assigned( Edit ) and ( Self.ComponentState = [] )
  then
    Edit.Text := Info;
end;
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.

Und ( Self.ComponentState = [] ) prüft ja auch nicht irgendwas abstruses von ausserhalb ab, sondern den Status deiner eigenen Komponente

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.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat