![]() |
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:
Gruß, Alex
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. |
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 ![]() ![]() 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 ![]() 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 |
Re: Threadstatus abfragen
Zitat:
|
Re: Threadstatus abfragen
Hallo Luckie!
Zitat:
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:
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.
with TObject.Create do
begin Whatever; Free; end; /EDIT: Gegenfrage: Nach deiner Logik fortgeführt: Was macht die Instanz, wenn ich diese gleich in 10 Variablen ablege?
Delphi-Quellcode:
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...
var
obj1, obj2, ... , obj10: TObject; begin obj1 := TObject.Create; obj2 := obj1; obj3 := obj1; ... obj10 := obj1; end; Gruss Yellow |
Re: Threadstatus abfragen
Mist! Ich wollte doch keinen Krieg provozieren.
Geht das hier erstmal für den Anfang:
Delphi-Quellcode:
Der Rest der Antwort von Yellow ist mir zu hoch für den Anfang.
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; Gruß, Alex |
Re: Threadstatus abfragen
Zitat:
|
Re: Threadstatus abfragen
@Yellow579
Zitat:
Viele Grüße DM |
Re: Threadstatus abfragen
Hallo Luckie, hallo DelphiManiac!
Ich zitiere nochmal den gesamten Beitrag: Zitat:
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 ![]() 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 |
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 |
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:
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.
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; Jetzt, wo ich den Code vor mir habe, ist mir auch klar geworden, dass das natürlich ohne Probleme funktioniert muss. |
Re: Threadstatus abfragen
Hallo Luckie!
Zitat:
Zitat:
Zitat:
Gruss Yellow |
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] |
Re: Threadstatus abfragen
Zitat:
Egal, euch noch viel Spass! |
Re: Threadstatus abfragen
Zitat:
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. |
Re: Threadstatus abfragen
Manche Sachen regeln sich von allein...
|
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. |
Re: Threadstatus abfragen
Zitat:
|
Re: Threadstatus abfragen
[OT]
:wiejetzt: Zitat:
... gibt es nicht wirklich wichtigeres ? :gruebel: ... hatte wir das nicht erst :gruebel: :evil: unglaublich... [/OT] |
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. |
Re: Threadstatus abfragen
Zitat:
1. Zitat:
[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:
Vielen Dank |
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 |
Re: Threadstatus abfragen
Zitat:
Hat jemand noch eine Idee zu meiner ersten Frage? Ist freeonterminate := true zu setzen eine Lösung? |
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 |
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:
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