Autor Beitrag
Heiko
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Fr 02.06.06 20:01 
Hallo,

ich mal wieder ein kleines Problem. Und zwar habe ich einen Thread im OnCreate erzeugt und gebe es im OnDestroy-Ereignis wieder frei. Nun möchte ich verhindern, dass der Thread beendet wird, bevor er erneut aufgerufen wird (also warten bis Execute beendet ist, bevor Execute aufgerufen wird). Ich habs jetzt mit WaitFor probiert, allerdings kommt er da nicht mehr raus, da der Thread schon vorher fertig ist. Was kann man dagegen am besten tun (ich will nicht noch eine Variable einfügen, die am Anfang eines Threads auf true und am Ende wieder auf falls gesetzt wird, um dass zu verhindern, da es sicherlich elegantere Lösungen gibt ;) )?
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Fr 02.06.06 20:33 
Eigentlich sollte Waitfor nicht hängen, selbst wenn der Thread die Execute-Methode schon verlassen hat. Verwendest du Synchronize im Thread oder das OnTerminate-Ergeignis?
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 03.06.06 20:17 
Nein, ich verwende beides nicht, da der Thread selber nur aus so 30 Zeilen besteht. (Der Thread nimmt dann aber eine Klasse, die so mal 2 Minuten arbeiten kann (SearchTool) ;) ), von daher bringt mir OnTerminate nichts (setzte es also auch nicht). Und Synchronisieren tue ich nicht, da ich alles über PostMessages (und beim Start des Threades eine Sendmessage) nutze. Aber bei WaitFor werden ja, laut der Doku von WaitFor (die Doku, die zu dem Quelltext von WaitFor dazu steht ;)), Messages abgearbeitet. Aber laut dem Debugger hängt er trotzdme bei WaitFor immer fest :(.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 03.06.06 20:24 
WaitFor nutzt, IIRC die WinAPI-Funktion WaitForSingleObject\WaitForMultipleObjects. Und wenn ich da richtig lieg, dann macht TThread.WaitFor nix anderes, als dem Scheduler von Windows zu sagen "Setze mich fort, wenn dieses Objekt freigegeben ist". In der gesamten Zeit, bis der Thread freigegeben ist, wird also kein Source vom wartenden Thread ausgeführt.

Dies kann umgangen werden, wenn man im wartenden Thread WaitFor schnell selber über eine While-Schleife in Verbindung mit dem Timeout-Rückgabewert der WaitFor-Methode nutzt und im Schleifenkörper Application.ProcessMessages einsetzt. Günstige Timeouts lägen dann bei etwa 100 bis 250ms.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 03.06.06 21:28 
Stimmt nicht. Zu mindestens steht im D2006-Source das hier ;) (der Codeausschnitt erklärt sich aber auch von alleine ;) ).

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
    repeat
      { This prevents a potential deadlock if the background thread
        does a SendMessage to the foreground thread }

      if WaitResult = WAIT_OBJECT_0 + 2 then
        PeekMessage(Msg, 000, PM_NOREMOVE);
      WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
      CheckThreadError(WaitResult <> WAIT_FAILED);
      if WaitResult = WAIT_OBJECT_0 + 1 then
        CheckSynchronize;
    until WaitResult = WAIT_OBJECT_0;
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Mi 26.07.06 11:44 
Ich hab das Problem gelöst. Ich den Thread nicht jedesmal neu erzeugen, wes wegen ich Execute mehrmals aufrufen wollte, aber da spielt der Thread nimmer mit ;).


PS: ICh räume gerade mal wieder meine offenen Fragen auf *g*