Autor Beitrag
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: So 10.06.07 22:58 
Rufe ich TThread.Terminate auf, bevor der Thread seine Execute-Methode betreten hat, so wird diese überhaupt nicht mehr aufgerufen. Ich habe dann also nicht die Möglichkeit der Applikation mitzuteilen, dass der Thread fertig ist (OnTerminate ist Schrott, wegen Synchronize). Ich frage mich, warum das so ist. Es macht das Design unnötig kompliziert.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mo 11.06.07 07:04 
Hi Spaceguide,

vielleicht verwendest Du die TThreadklasse nicht richtig...? Ich vermute mal, Du erzeugst sie im 'Suspended'-Modus und weckst Sie bei Bedarf aus. Unpraktisch, weil ... Ich verwende immer ein Synchronisationsobjekt (Semaphore). Du kannst es Dir aber auch einfach machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Procedure TMyThread.Execute;
Begin
  While Not Terminated do Begin
// ... Hier Dein Code (oder auch: If Not Terminated Then ...)
  End
End;

...
Procedue StopMyThread;
Begin
  With MyThread Do Begin
    Terminate;
    If Suspended Then Resume;
    WaitFor;
  End
End;

Wenn ein Thread ständig im Hintergrund irgendetwas ausführt, tendiere ich sowieso zu einer Semaphore, weil ich dann aufwecken/einschlafen sehr sauber von außen kontrollieren kann. Mit 'Suspend/Resume' habe ich doch keine Kontrolle, wo und wann genau der Thread einschläft.

_________________
Na denn, dann. Bis dann, denn.
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Mo 11.06.07 07:35 
Ne, daran liegt's nicht. Die Threads werden nicht suspended gestartet. Nachdem ein Thread erzeugt wird, geht's ja gleich im Hauptprogramm weiter. Da kann es vorkommen (z.B. wenn der Benutzer ESC drückt), dass der Thread sofort ein Terminate abbekommt. Es gibt eine kurze Zeitspanne innerhalb des Threads zwischen Create und Execute (was auch immer der da macht). So kann es vorkommen, dass vom Hauptprogramm das Terminate kommt, bevor er ins Execute geht und dann geht er garnicht mehr ins Execute, weil in den RTL-Sourcen ein


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
    if not Thread.Terminated then
    try
      Thread.Execute;
    except
      Thread.FFatalException := AcquireExceptionObject;
    end;


steht.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mo 11.06.07 08:24 
Oh :shock: , das ist ja crank.

Na denn:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Procedure TMyThread.AcquireTerminate;
Begin
  fPleaseTerminate := True;
End;

Procedure TMyThread.Execute;
Begin
  While not fPleaseTerminate do begin
// ..Bla fasel
  End;
  Terminate; // Ob das nötig ist, weiss nich
End;

Ungetestet, aber warum sollte das nicht laufen ?

_________________
Na denn, dann. Bis dann, denn.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 11.06.07 11:34 
user profile iconSpaceguide hat folgendes geschrieben:
Rufe ich TThread.Terminate auf, bevor der Thread seine Execute-Methode betreten hat

Machst du das im realen Leben auch so, einen Raum verlassen, den du noch gar nicht betreten hast? :roll: da der Thread noch gar nicht ausgeführt wird, gibt es auch nichts zu beenden.

Zitat:
so wird diese überhaupt nicht mehr aufgerufen.

Ja was denn nun? Du brichst etwas ab bevor es angefangen hat und dann wunderst du dich, dass es nicht anfängt?

Zitat:
Ich habe dann also nicht die Möglichkeit der Applikation mitzuteilen, dass der Thread fertig ist

Wie so fertig? Du hast doch alles abgewürgt.

Zitat:
(OnTerminate ist Schrott, wegen Synchronize).

Dann machst du was falsch. Und wie es aussieht, ziemlich viel.

Zitat:
Es macht das Design unnötig kompliziert.

Ich glaube, dein verkorkstes Programmdesign macht das ganze unnötig kompliziert. Du solltest mal geneuer erklären, was du machst, und was du erreichen willst.
Spaceguide Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Mo 11.06.07 17:54 
Der Ablauf ist im Groben so:

(1) Threads werden gestartet, Hauptprogramm geht zurück in den Message Loop.
(2) Threads arbeiten
(3) Threads sind fertig, signalisieren das am Ende von Execute per PostMessage ans Hauptprogramm
(4) Hauptprogramm reagiert auf Message, beendet Threads (WaitFor, Free)

Das Signalisieren per PostMessage ist meiner Meinung nach die sauberste Art zu signalisieren, dass ein Thread fertig ist. OnTerminate kann in Verbindung mit WaitFor zu Deadlocks führen. Sieht doch alles sehr simpel und garnicht vermurkst aus.