Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Threadstatus abfragen (https://www.delphipraxis.net/116632-threadstatus-abfragen.html)

Schwedenbitter 3. Jul 2008 11:45


Threadstatus abfragen
 
Hallo,

ich habe hier (immer noch) Delphi 6. Ich möchte gern etwas in einem Thread ablaufen lassen und habe dazu ein kleines Testprogramm geschrieben. Für Hinweise zur Verbesserung im Allgemeinen bin ich zugänglich. Nun aber zu meiner Frage:

Gibt es bei TThread eine Eigenschaft oder sonstwas, womit ich ohne Probleme abfragen kann, ob der Thread bereits existiert und ggf. nur angehalten ist?

Bislang löse ich das über eine globale Variable, was mir aber nicht wirklich gefällt. Das Formular besteht aus einem TLabel für die Ausgabe und 3 Buttons für "Start", "Anhalten" unmd "Beenden" des Threads:

Delphi-Quellcode:
Unit _Main;

Interface

Uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls;

Type
   TTestThread   = Class(TThread)
                  Procedure Execute; override;
                 End;
   TForm1      = Class(TForm)
                  Label1   : TLabel;   Button1   : TButton;
                  Button2   : TButton;   Button3   : TButton;
                  Procedure FormCreate(Sender: TObject);
                  Procedure Button1Click(Sender: TObject);
                  Procedure Button2Click(Sender: TObject);
                  Procedure Button3Click(Sender: TObject);
                 End;

Var
   Form1            : TForm1;
   Exists         : Boolean;
   SecondProcess   : TTestThread;

Implementation

{$R *.dfm}

Procedure TForm1.FormCreate(Sender: TObject);
Begin
   Exists:=False;
End;

Procedure TTestThread.Execute;
Var
   I            : Integer;
Begin
   For I:=0 To MaxInt Do
   Begin
      Form1.Label1.Caption:=IntToStr(I);
      If Terminated Then
      Begin
         Exit;
      End;
   End;
   Form1.Label1.Caption:='Thread beendet.';
End;

Procedure TForm1.Button1Click(Sender: TObject);
Begin
   Button1.Enabled:=False;
   Button2.Enabled:=True;
   Button3.Enabled:=True;
   If Not Exists Then   // Thread existiert schon?
   Begin
      SecondProcess:=TTestThread.Create(True);
      SecondProcess.Priority:=tpLower;
      Exists:=True;
   End;
   SecondProcess.Resume;
End;

Procedure TForm1.Button2Click(Sender: TObject);
Begin
   SecondProcess.Suspend;
   Button1.Enabled:=True;
   Button2.Enabled:=False;
   Label1.Caption:='Thread angehalten.';
End;

Procedure TForm1.Button3Click(Sender: TObject);
Begin
   SecondProcess.Terminate;
   Button3.Enabled:=False;
   Button2.Enabled:=False;
   Button1.Enabled:=True;
   Exists:=False;
   Label1.Caption:='Thread beendet.';
End;

End.
Gruß, Alex

Yellow579 3. Jul 2008 12:17

Re: Threadstatus abfragen
 
Hallo Schwedenbitter!

Zu deiner eigentlichen Frage: Ob der Thread an sich existiert, kannst du mit der Überprüfung der Instanzenvariablen erreichen (<> nil, sprich Delphi-Referenz durchsuchenAssigned()). Voraussetzung dafür ist aber, dass diese Variable ordentlich auf nil gesetzt wird, wenn der Thread beendet wird. Dies kannst du u.a. dadurch erreichen, in dem du dem Thread ein OnTerminate Ereignis zuweist und darin diese Variable auf nil setzt. Damit kannst du die Existenz soweit sicher vom Hauptprogramm aus abfragen. Und wenn dieser existiert bleibt nur noch die Frage bestehen, ob er z.Z. suspendiert ist. Dies kannst du mit der Eigenschaft Delphi-Referenz durchsuchenSuspended abfragen.

Und nun noch ein paar dringliche Hinweise: Der Thread läuft asynchron zu dem VCL Hauptthread und somit allen anderen VCL Aktivitäten. Von daher müssen Zugriffe auf Elemente des anderen Threads (VCL Mainthread, besitzt jede VCL Anwendung) synchronisiert werden. Mit anderen Worten: Es ist strengstens verboten auf VCL Elemente des VCL Threads von deinem Thread aus zu zu greifen. Ganz speziell sind es in deinem Code die Zugriffe auf Label1. Abhilfe schafft hier die Methode Delphi-Referenz durchsuchenSynchronize von TThread.

Dann sollte man die Verwendung von globalen Variablen (wie z.B. Form1) grundlegend vermeiden. Wenn, dann übergebe die Instanz und halte sie lokal im Thread (aber wie gesagt: ausschliesslich synchronisierte Zugriffe!). Vor allem ist es unverständlich, warum du z.B. Exists und SecondProcess nicht als Member des Formulars definiert hast. Instanziier eine zweite Form1 und du hast die misere, da alles doppelt ist, nur die beiden Variablen nicht - die gibs nur einmal und der erste Thread ist auch speichertechnisch verloren, da seine Instanz verloren ist.

Dein Threadcode würde mit einer While Schleife (mit 2 Bedingungen: i Endwertvergleich & Terminated) deutlich besser umsetzbar sein als der harte Exit auf Terminated im jetzigen Code.

Dann beachte bitte die Hinweise, denn du solltest bei der Execute Methode des Threads einen Hinweis bekommen, dass die Sichtbarkeit der überschriebenen Methode nicht übereinstimmen. Execute ist im protected Abschnitt deklariert und du überschreibst diese aber im public (afair vllt. sogar auch published) Bereich der Klasse.

Gruss
Yellow

Luckie 3. Jul 2008 12:37

Re: Threadstatus abfragen
 
Zitat:

Zitat von Yellow579
Hallo Schwedenbitter!

Zu deiner eigentlichen Frage: Ob der Thread an sich existiert, kannst du mit der Überprüfung der Instanzenvariablen erreichen (<> nil, sprich Delphi-Referenz durchsuchenAssigned()). Voraussetzung dafür ist aber, dass diese Variable ordentlich auf nil gesetzt wird, wenn der Thread beendet wird. Dies kannst du u.a. dadurch erreichen, in dem du dem Thread ein OnTerminate Ereignis zuweist und darin diese Variable auf nil setzt.

Bist du sicher dass das geht? Du ziehst dem Threadobjekt ja quasi den Teppich unter den Füßen weg, während es noch existiert.

Yellow579 3. Jul 2008 12:52

Re: Threadstatus abfragen
 
Hallo Luckie!

Zitat:

Zitat von Luckie
Bist du sicher dass das geht? Du ziehst dem Threadobjekt ja quasi den Teppich unter den Füßen weg, während es noch existiert.

Ich bin erschüttert, weil das was du schreibst kann nur zu Problemen führen, wenn du aus dem Thread heraus auf die externe (in der Form) liegende eigene Instanzenvariable zugreifst. Aber ich denke mal, du hast da nur einen kleinen Denkfehler.

Ein Objekt greift soweit niemals auf seine eigene Instanzenvariable zu, somit kann das sonstwas sein. Genausogut nil. Nach Frage zu urteilen, sollte es in deinen Augen auch niemals folgendes funktionieren, da es erst gar keine Variable gibt, in der die Instanz abgelegt wird:

Delphi-Quellcode:
with TObject.Create do
begin
  Whatever;
  Free;
end;
Die Instanzenvariable ist nur ein Pointer und kann sonstwo hinzeigen, das interessiert die Instanz im Speicher (deren Adresse in der Variablen hinterlegt ist) herzlich wenig.

/EDIT: Gegenfrage: Nach deiner Logik fortgeführt: Was macht die Instanz, wenn ich diese gleich in 10 Variablen ablege?

Delphi-Quellcode:
var
  obj1, obj2, ... , obj10: TObject;
begin
  obj1 := TObject.Create;
  obj2 := obj1;
  obj3 := obj1;
  ...
  obj10 := obj1;
end;
Deine Logik hätte aber umgesetzt ihren Reiz, weil dann wären z.B. nach einem FreeAndNil() auch gleich alle anderen Instanzenvariablen nil, egal wo diese liegen. Das hätte für manchen Anfänger schon seinen Reiz...

Gruss
Yellow

Schwedenbitter 3. Jul 2008 13:07

Re: Threadstatus abfragen
 
Mist! Ich wollte doch keinen Krieg provozieren.
Geht das hier erstmal für den Anfang:

Delphi-Quellcode:
Procedure TTestThread.Ausgabe;
Begin
   Form1.Label1.Caption:=S;
End;

Procedure TTestThread.Execute;
Var
   I            : Integer;
Begin
   I:=0;
   While (I<=MaxInt) And Not Terminated Do
   Begin
      S:=FormatFloat('#,##0',I);   Synchronize(Ausgabe);
      Inc(I);
   End;
   S:='Thread beendet.';   Synchronize(Ausgabe);
End;
Der Rest der Antwort von Yellow ist mir zu hoch für den Anfang.

Gruß, Alex

Luckie 3. Jul 2008 13:17

Re: Threadstatus abfragen
 
Zitat:

Zitat von Yellow579
Hallo Luckie!

Zitat:

Zitat von Luckie
Bist du sicher dass das geht? Du ziehst dem Threadobjekt ja quasi den Teppich unter den Füßen weg, während es noch existiert.

Ich bin erschüttert, weil das was du schreibst kann nur zu Problemen führen, wenn du aus dem Thread heraus auf die externe (in der Form) liegende eigene Instanzenvariable zugreifst. Aber ich denke mal, du hast da nur einen kleinen Denkfehler.

Ich verstehe jetzt den Zusammenhang nicht so ganz. Ich mache gar nichts. Ich stelle nur in Frage, ob der Vorschlag meines Vorposters funktionieren kann. Er will ja die Objektvariable in einem Ereignis der Objektvariablen selber auf nil setzen.

DelphiManiac 3. Jul 2008 13:44

Re: Threadstatus abfragen
 
@Yellow579

Zitat:

Hallo Luckie!

Luckie hat folgendes geschrieben:
Bist du sicher dass das geht? Du ziehst dem Threadobjekt ja quasi den Teppich unter den Füßen weg, während es noch existiert.


Ich bin erschüttert, weil das was du schreibst kann nur zu Problemen führen, wenn du aus dem Thread heraus auf die externe (in der Form) liegende eigene Instanzenvariable zugreifst. Aber ich denke mal, du hast da nur einen kleinen Denkfehler.
Ich glaube hier ist jemand in der Spalte verrutscht, der Beitrag kam ja nicht von Luckie, sonder von Schwedenbitter, selbst wenn Luckie das über Threads geschrieben hätte, dann würde es wahrscheinlich sogar stimmen :lol: ...

Viele Grüße
DM

Yellow579 3. Jul 2008 14:49

Re: Threadstatus abfragen
 
Hallo Luckie, hallo DelphiManiac!

Ich zitiere nochmal den gesamten Beitrag:

Zitat:

Zitat von Luckie
Zitat:

Zitat von Yellow579
Hallo Luckie!

Zitat:

Zitat von Luckie
Bist du sicher dass das geht? Du ziehst dem Threadobjekt ja quasi den Teppich unter den Füßen weg, während es noch existiert.

Ich bin erschüttert, weil das was du schreibst kann nur zu Problemen führen, wenn du aus dem Thread heraus auf die externe (in der Form) liegende eigene Instanzenvariable zugreifst. Aber ich denke mal, du hast da nur einen kleinen Denkfehler.

Ich verstehe jetzt den Zusammenhang nicht so ganz. Ich mache gar nichts. Ich stelle nur in Frage, ob der Vorschlag meines Vorposters funktionieren kann. Er will ja die Objektvariable in einem Ereignis der Objektvariablen selber auf nil setzen.

Wie man sieht, zitiere ich Luckie und dies steht auch so in seinem Beitrag.

Vorposter = Yellow579 = ich.

Der Vorschlag kam auch von mir, somit Vorposter = Yellow579 = ich.

Und welche Spalte meinst du bitteschön? Ich habe hier nur eine...

Und zu der Frage: Was hat die Instanzenvariable mit einem Event einer Instanz zu tun? Die Instanz referenziert niemals die Instanzenvariable, weil es eine n:1 Beziehung ist. Umgekehrt referenziert die Instanzenvariable die Instanz...

Und wenn diese Instanz eine Methode aufruft, was die Closure's ja nunmal nur sind, dann wird self über den Stack übergeben und nicht ein Pointer auf die Instanzenvariable. Diese spielt in der gesamten Abarbeitung überhaupt keine Rolle, von daher verstehe ich überhaupt nicht wie du, Luckie, auf die Idee kommst, dass es was miteinander zu tun hat.

Ich kann in jedem Ereignis eines Objektes dessen Instanzenvariable verändern (somit auch nil setzen), wie ich lustig bin. Spätestens beim Zugriff (von außen wohlgemerkt), habe ich dann mehr oder minder ein Problem, aber mit nil und einer Abprüfung kein Problem (siehe Beitrag zuvor). Und ein Zugriff von innen, also aus der Instanz heraus auf die Variable - ich kann mich nur wiederholen - findet nicht statt. Einzige Möglichkeit: es wurde explizit so reinprogrammiert (siehe Nutzung globaler Instanzenvariablen) - und dies ist der einzige Weg und die einzige Begründung, welche eine solche Frage aufkommen lassen kann. Von daher die Erschütterung über die Frage.

[OT]
Es ist erschütternd, da kommt man in dieses Forum und teilt sein Wissen mit und es wird einem Widersprochen - aber dann gleich deutlich mit Sprüchen wie RTFM und ich gebe einem anderen Recht, weil er mehr Postings hat. Kleinlaut gibs dann nachher die Korrektur.
Hier weise ich eindeutig mit Zitaten auf den bezogenen Inhalt hin und schon meint man, ich lese schief. Der Inhalt war doch ganz genau auf diesen Beitrag zugeschnitten und entsprechend geschrieben. Es ist eindeutig, dass ich mich mit keinem Wort auf den Beitrag vom Threadersteller beziehe. Und dieser hat keinen solchen Vorschlag gemacht wie ich.

Bitte, lest die Beiträge in Ruhe durch, durchdenkt sie und dann postet. Am besten auch vorher mal ausprobieren und nicht gleich Blasphemie Ketzer schreien...

Witziges Forum hier...
[/OT]

Grüsse
Yellow

PMM 3. Jul 2008 14:59

Re: Threadstatus abfragen
 
... Er will ja die Objektvariable in einem Ereignis der Objektvariablen selber auf nil setzen.

Das ist zwar etwas "gewöhnungsbedürftig" aber an dieser Stelle völlig OK denke ich. Es bedeutet, dass das Objekt, zumindest über diese Objektvariable, nicht mehr erreichbar ist. Damit wird, im diskutierten Fall, "nach außen" signalisiert, dass der Thread nun tatsächlich beendet wurde - was ja asynchron über das Betriebssytem erfolgt und ansonsten gar nicht so einfach festzustellen ist.

Und das alles ganz unabhängig davon wer wann, warum was gepostet hat :)

PMM

Luckie 3. Jul 2008 15:03

Re: Threadstatus abfragen
 
Noch mal, ich habe nicht widersprochen, sondern nur etwas in Frage gestellt. Du hast folgendes vorgeschlagen:
Delphi-Quellcode:
unit Unit2;

interface

uses
  SysUtils, Classes;

type
  TTest = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  end;

implementation

{ Wichtig: Methoden und Eigenschaften von Objekten in VCL oder CLX können
   nur in Methoden verwendet werden, die Synchronize aufrufen, z.B.:

      Synchronize(UpdateCaption);

   wobei UpdateCaption so aussehen könnte:

    procedure TTest.UpdateCaption;
    begin
      Form1.Caption := 'In einem Thread aktualisiert';
    end; }

{ TTest }

procedure TTest.Execute;
var
  i: Integer;
  s: String;
begin
  for i := 0 to 9999 do
  begin
    s := s + IntToStr(i);
  end;
end;

end.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    TestThread: TThread;
    procedure OnTerminate(Sender: TObject);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TestThread := TTest.Create(True);
  TestThread.OnTerminate := OnTerminate;
  TestThread.Resume;
end;

procedure TForm1.OnTerminate(Sender: TObject);
begin
  TestThread := nil;
end;
Und ich habe in Frage gestellt, ob man in einem Ereignis eines Objektes, selbiges auf nil setzen kann. Hintergrund war der, dass wenn man in einem Destruktor die Objektreferenz auf nil setzt, es zu einer Exception kommt. Das hatte ich im Hinterkopf.

Jetzt, wo ich den Code vor mir habe, ist mir auch klar geworden, dass das natürlich ohne Probleme funktioniert muss.

Yellow579 3. Jul 2008 15:47

Re: Threadstatus abfragen
 
Hallo Luckie!

Zitat:

Zitat von Luckie
Hintergrund war der, dass wenn man in einem Destruktor die Objektreferenz auf nil setzt, es zu einer Exception kommt. Das hatte ich im Hinterkopf.

Das ist ein definitiv anderer Fall da es in dem Falle der Instanz an sich an den Kragen geht. Alles hier besprochene bezieht sich nur auf Dinge ausserhalb der Instanz und niemals der Instanz selber.

Zitat:

Zitat von Luckie
Jetzt, wo ich den Code vor mir habe, ist mir auch klar geworden, dass das natürlich ohne Probleme funktioniert muss.

Zitat:

Zitat von Yellow579
Bitte, lest die Beiträge in Ruhe durch, durchdenkt sie und dann postet. Am besten auch vorher mal ausprobieren und nicht gleich Blasphemie Ketzer schreien...

Hauptsache alle haben es verstanden und es funktioniert. Noch wichtiger: Die Problemlösung löst das Problem anstatt drumherum zu bauen.

Gruss
Yellow

DelphiManiac 3. Jul 2008 16:08

Re: Threadstatus abfragen
 
[OT]
@Yello579
Ich gebe hier niemanden recht, aufgrund von N-Beiträgen...
Es geht ja auch gar nicht darum, dein Beitrag hat sich nur wirklich komisch angehört.
Ich meine jetzt nicht aus fachlicher Sicht. Ich finde nur, das man nicht "erschüttert" sein muss über eine Frage, deshalb dachten wohl viele, dass du dich auf den Beitrag von Schwedenbitter beziehst...(u.a. ich). Aber du hast dich ja wirklich auf den Beitrag von Luckie bezogen, also lag ich falsch, sorry.

Ich bin froh, dass in dem Forum nicht jede Lösung gleich abgenickt wird, sondern auch hinterfragt wird,... wenn die Lösung sich als zweifelsfrei erkenntlich gibt, dann haben ja alle was davon.

Jetzt aber genug Off-Topic..

[/OT]

Yellow579 3. Jul 2008 16:48

Re: Threadstatus abfragen
 
Zitat:

Zitat von DelphiManiac
[OT]
@Yello579
Ich gebe hier niemanden recht, aufgrund von N-Beiträgen...[/OT]

Das bezog sich auch nicht auf dich, sondern auf den verlinkten Beitrag.

Egal, euch noch viel Spass!

Luckie 3. Jul 2008 19:39

Re: Threadstatus abfragen
 
Zitat:

Zitat von Yellow579
Bitte, lest die Beiträge in Ruhe durch, durchdenkt sie und dann postet. Am besten auch vorher mal ausprobieren und nicht gleich Blasphemie Ketzer schreien...

Jetzt platz mir aber gleich der Kragen. Ich habe lediglich deinen Vorschlag hinterfragt nicht mehr nicht weniger. Ich habe dich weder persönlich angegriffen noch habe deinen Vorschlag als Scheiße abgetan! Das habe ich dir jetzt schon mindestens drei mal gesagt, während deine persönlichen Angriffe mir gegenüber immer heftiger wurden. Aber ich war mi nicht bewußt dass ich es hier an scheinen mit einer unfehlbaren Programmier-Gottheit zu tun habe.

Solltest du nicht bereit sein über deine Vorschläge zu diskutieren, dann bist du hier eindeutig falsch. Aber wie ich sehe, hast du schon deine Konsequenzen gezogen. Gut so.

DelphiManiac 3. Jul 2008 19:58

Re: Threadstatus abfragen
 
Manche Sachen regeln sich von allein...

marabu 3. Jul 2008 20:20

Re: Threadstatus abfragen
 
Mahlzeit.

Da findet alle paar Monde mal ein neues Mitglied zu uns in die DP, das in der Lage ist sich auszudrücken, sich sogar die Zeit dazu nimmt und auch noch versteht worüber es schreibt und dann wird es nicht einmal angemessen begrüßt. Yellow hat hier wohlgemerkt keine Hilfe gesucht, sondern Hilfe angeboten. Jetzt habt ihr ihn weggeekelt. Ihr täuscht euch, wenn ihr glaubt, die DP könne sich sowas leisten. Ich wünsche mir da mehr Sozialkompetenz, insbesondere von einem Moderator.

Gute Nacht allerseits.

Luckie 3. Jul 2008 21:04

Re: Threadstatus abfragen
 
Zitat:

Zitat von marabu
Ich wünsche mir da mehr Sozialkompetenz, insbesondere von einem Moderator.

Falls du mich meinst. Nochmal ich habe weder seine Kompetenz angezweifelt noch bin ich der Meinung, dass ich ihn weg geeckelt habe. Alles, was ich getan habe, war seinen Lösungsvorschlag zu hinterfragen, weil ich ursprünglich der Meinung war, dass es nicht funktionieren könnte. Soll ich, nur weil sich jemand persönlich angegriffen, in seiner Ehre und in seiner Unfehlbarkeit fühlt, nichts sagen und keine Zwiefel äußern? Wenn wir soweit sind, dann sagt bitte Bescheid, denn dann brauchen wir kein Diskussionsforum und ich verlasse auf der Stelle das Forum.

haentschman 3. Jul 2008 21:09

Re: Threadstatus abfragen
 
[OT]
:wiejetzt:
Zitat:

und ich verlasse auf der Stelle das Forum.
... das scheint in letzter Zeit um sich zu greifen :gruebel:
... gibt es nicht wirklich wichtigeres ? :gruebel:
... hatte wir das nicht erst :gruebel:

:evil: unglaublich...
[/OT]

Daniel 3. Jul 2008 21:32

Re: Threadstatus abfragen
 
Ich bitte um allseitige Contenance.

Michael hatte einen Lösungsansatz in Frage gestellt - das ist völliglegitim. In Beitrag #10 hat er seinen Irrum bemerkt und damit hätte die Sache erledigt sein können. Aber ganz offensichtlich waren hier für die Entscheidung von yellow noch weitere Faktoren im Spiel, die mit diesem Thema nicht unmittelbar etwas zutun haben.

Die Beiträge #14 und #17 führe ich gegenwärtig auf Stress und ggf. schlechte Laune zurück. Das ist keinesfalles optimal, aber auch das müsst Ihr einem team-Mitglied zugestehen, ohne dass hieraus gleich eine grundsätzliche Richtung der DP abgeleitet wird.

Ich bedaure es, wenn konstruktive Mitglieder das Forum verlassen, aber das gehört leider dazu und manchmal kommen sie ja wieder.

Und nun bitte zurück zum Thema - weiteres OffTopic in diesem Thread blende ich aus.

Viktorii 17. Jul 2008 08:26

Re: Threadstatus abfragen
 
Zitat:

Zitat von Daniel
Und nun bitte zurück zum Thema - weiteres OffTopic in diesem Thread blende ich aus.

Wird gemacht. Ich habe zwei (hoffentlich nicht zu dumme) Fragen:

1.
Zitat:

Zitat von Luckie
Delphi-Quellcode:
unit Unit2;

interface

uses
  SysUtils, Classes;

type
  TTest = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  end;

implementation

{ Wichtig: Methoden und Eigenschaften von Objekten in VCL oder CLX können
   nur in Methoden verwendet werden, die Synchronize aufrufen, z.B.:

      Synchronize(UpdateCaption);

   wobei UpdateCaption so aussehen könnte:

    procedure TTest.UpdateCaption;
    begin
      Form1.Caption := 'In einem Thread aktualisiert';
    end; }

{ TTest }

procedure TTest.Execute;
var
  i: Integer;
  s: String;
begin
  for i := 0 to 9999 do
  begin
    s := s + IntToStr(i);
  end;
end;

end.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    TestThread: TThread;
    procedure OnTerminate(Sender: TObject);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TestThread := TTest.Create(True);
  TestThread.OnTerminate := OnTerminate;
  TestThread.Resume;
end;

procedure TForm1.OnTerminate(Sender: TObject);
begin
  TestThread := nil;
end;

Okay, habe ich soweit verstanden... Ich habe es bis jetzt immer so gemacht, dass ich ein Object mit freeandnil freigegeben habe, nachdem ich es nicht mehr brauche. Funktioniert das jetzt auch noch, wo der Zeiger ja schon nil ist? Wenn nein, wie gebe ich den Speicher dann frei?

[edit]
kann man sich nicht auch einfach ein Feld im Thread Objekt erzeugen, welches mit true initialisiert wird und bei onTerminate auf false gesetzt wird? Diese könnte man dann ja
auch abfragen... Wiese macht man die Erkennung hier mit dem Zeiger?
[/edit]




2.
Zitat:

Zitat von Schwedenbitter
Delphi-Quellcode:
Procedure TTestThread.Ausgabe;
Begin
   Form1.Label1.Caption:=S;
End;

Procedure TTestThread.Execute;
Var
   I            : Integer;
Begin
   I:=0;
   While (I<=MaxInt) And Not Terminated Do
   Begin
      S:=FormatFloat('#,##0',I);   Synchronize(Ausgabe);
      Inc(I);
   End;
   S:='Thread beendet.';   Synchronize(Ausgabe);
End;

Ist diese Verwendung von Synchronize mit VCL Komponenten so richtig?

Vielen Dank

DelphiManiac 17. Jul 2008 13:38

Re: Threadstatus abfragen
 
Hallo!

Die Verwendung von Synchronize ist absolut richtig,
wobei man natürlich sich fragen muss, ob der Thread unbedingt die Instanz Form1 kennen muss?
Oder ob man nicht einfach eine Callbackfunktion macht, die der "Threadersteller" (zB.: Form1) registriert.
Aber das ist nur eine Designfrage, ansonsten genau richtig! 8)

Gruß
DM

Viktorii 13. Aug 2008 10:43

Re: Threadstatus abfragen
 
Zitat:

Zitat von DelphiManiac
wobei man natürlich sich fragen muss, ob der Thread unbedingt die Instanz Form1 kennen muss?
Oder ob man nicht einfach eine Callbackfunktion macht, die der "Threadersteller" (zB.: Form1) registriert.

Das mit der Callbackfuntion verstehe ich nicht so ganz. Könntest du da vielleicht ein kleines Beispiel angeben?


Hat jemand noch eine Idee zu meiner ersten Frage? Ist freeonterminate := true zu setzen eine Lösung?

oki 13. Aug 2008 11:14

Re: Threadstatus abfragen
 
Hi Viktorii,

ich denke die Lösung mit dem Ereignis OnTerminate ist vollkommen ausreichend. Das mit dem Callback ist eine Möglichkeit dem Thread einen Methodenzeiger einer anderen Instanz mitzugeben, die dieser dann aufruft. Ob das aber dann nicht wieder Konflikte bezüglich der Asynchronität verursacht weis ich nicht.

Eine weitere Möglichkeit ergibt sich noch, in dem man eine eigene UserMessage definiert. Über SendMessage oder PostMessage kann dann eine Botschaft an das creierende Fenster gesendet werden um die Nachricht des Terminierens los zu werden. Damit ergibt sich dann natürlich auch die Möglichkeit eine Liste von Empfängern für diese Nachricht zu erstellen. so lange der Thread existiert könnten dort dann sämtliche Instanzen (die über die Botschaftswarteschlange erreicht werden können) registriert werden und der Thread benachrichtigt dann alle eingetragenen.

Ich persönlich bevorzuge aber das Ereignis.

Gruß oki

smallsmoker 13. Aug 2008 12:11

Re: Threadstatus abfragen
 
[ot]
oh mein gott

ich habe jetzt den gesamten thread bishierhin gelesen weil ich nur wissen wollte wie tthread funktioniert so
und dann das gelb123 sagt irgendetwas luckie fragt nach ob das stimmt und dann das:
Zitat:

Ich bin erschüttert
haha da musste ich schon lachen xD
aber dann der ganze rest zum wegbrüllen das lief ungefähr so:

gelb: das ist aber so
luckie: ich weiß war mein fehler
gelb: das ist aber so
luckie: ja habe ich ja auch nicht angezweifelt
gelb: das ist aber so

gelb: ich gehe jetzt

haahahahah
[ot]

ich entschuldige mich an dieser stelle falls das jetzt wiederum jemanden beleidigt, (er kann ja auch das forum verlassen :lol: )

mfg smallsmoker

p.s.: ich bin erschüttert von diesem thread


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:20 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