Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 08:10

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Aug 14, 2008 04:52 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Hey,

wie der Titel schon versucht zu illustrieren: Ich habe ein Threadingproblem unter TurboDelphi. Abstrahiert gesehen will ich einfach nur einen Thread starten und sein Ende abwarten. Das Ganze soll dann einfach immer wieder und wieder geschehen. Sinn macht es zugegeben so wie es aussieht keinen, aber das ist nur die oberste Abstraktion auf der Fehlersuche.
Nun aber dieser Code eines Beispielprojects:
Code:
  1. var
  2.   BoolVar: Boolean;
  3.  
  4. procedure TForm1.FormCreate(Sender: TObject);
  5. begin
  6.   MyThread := TMyThread.Create(True);
  7. end;
  8.  
  9. procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
  10. begin
  11.   Done := False;
  12.  
  13.   BoolVar := True;
  14.   MyThread.Resume;
  15.  
  16.   while BoolVar do
  17.   begin
  18.     Sleep(1000);
  19.     Memo1.Lines.Add('Warte auf Thread...');
  20.   end;
  21.   Memo1.Lines.Add('End Idle');
  22.  
  23. end;
  24.  
  25. procedure TMyThread.Execute;
  26. begin
  27.   BoolVar := False;
  28.   Suspend;
  29. end;


führt den Thread exakt 1x aus und befördert die while- zur Ehren-Endlosschleife.
Daher 2 Fragen:
1. Warum passiert das?
2. Gibt es einen besseren Weg auf das Ende des Threads zu warten?

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 14, 2008 08:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Suspend ist keine Ende des Thread. Es verhindert lediglich dessen Ausführung. Vergleichbar auch mit einem "Sleep(infinity)". Der Thread existiert aber weiterhin. Er wird nur beendet, wenn die Threadmethode (Execute) verlassen wird. Suspend solltest du nur benutzen, wenn du die Ausführung eines Threads verhindern möchtest aber ihn nicht komplett beenden willst. Wobei in der MSDN auch steht, dass es sich dabei um einen Suspendcounter handelt.

Einen Thread kann man nur ein mal starten. Also wenn er durchgelaufen ist, dann gilt er als beendet. Wenn du dann noch mal Resume aufrufst wird der Thread nicht noch einmal gestartet. Du bräuchtest dann eine neue Instanz von deinem Thread oder aber du musst deinen Thread so aufbauen, dass er wartet bis ihm eine neue Aufgabe mitgeteilt wurde. Also eine Endlosschleife innerhalb von Execute die auf Terminated wartet bzw evtl auch auf ein TEvent (wegen arbeit).

Um auf das Ende eines Threads zu warten würde ich eher OnTerminate benutzt. Also Anwendung sperren. Thread erstellen. Das Event OnTerminate zuweisen. Thread mit Resume starten und dann so lange warten bis das Event ausgelöst wird. Da du auch einen Sender bekommst könntest du so auch unterscheiden welcher sich da gerade meldet. Du müsstest dann wärend der Ausführung deinen Anwendung in einen Zustand versetzen in dem nichts passieren kann. Also evtl verschiedene Komponenten sperren etc. Der Vorteil wäre, dass deine Anwendung weiterhin vollständig intakt bleibt. Im OnTerminate darfst du den Thread aber nicht freigeben. Das führt zu einem 100%tigen Deadlock.

Alternativ kannst du auch mit TThread.WaitFor warten. Aber diese Methode wartet so lange bis er fertig ist. Wenn du pech hast reagiert deine Anwendung dann für Minuten gar nicht mehr. Du kannst auch die WindowsApi Funktion WaitForSingleObject benutzen. Der übergibt man TThread.Handle und eine Zeit die maximal gewartet werden soll. Dann könntest du alle 50 ms nachschauen ob sonst noch alles in Ordnung ist. Aber Normalerweise würde ich die eventbasierte Methode vorziehen. Das kommt dem Prinzip von Windows und der Threads am nächsten. Und du würdest nicht stumpf blockieren.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 14, 2008 17:41 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Danke für die Antwort.
Richtig, der Thread läuft ja nur so durch. Irgendein kleines Detail vergesse ich beim Durchdenken irgendwie immer. Tatsächlich scheint die Suspend/Resume-Lösung doch noch zu funktionieren, wenn ich dafür sorge, dass der Thread immer wieder durchlaufen kann.
Wenn es aufgrund der Laufzeit nötig wird, werde ich auf die Terminate-Lösung umsteigen.

MfG


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 16 Queries | GZIP : On ]