Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi trotz WaitFor wird nicht gewartet bis Thread beendet ist (https://www.delphipraxis.net/72641-trotz-waitfor-wird-nicht-gewartet-bis-thread-beendet-ist.html)

TomDooley 4. Jul 2006 13:12


trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Hallo

Ich möchte in meinem Hauptthread warten bis mein Hilfsthread beendet ist. Alles funktioniert ohne Probleme solange ich meine blockierende "Aufräume-Funktion" Close im Hilfsthread nicht aufrufe:

Delphi-Quellcode:
begin
  Hilfsthread.Terminate;
  Hilfsthread.WaitFor;
  //alles andere freigeben
end;

procedure Hilfsthread.Execute;
begin
  while not Terminated do
  begin
    //...
  end;
  Close; //Aufräumen; ohne diese blockierende Funktion die etwas länger dauert funktioniert alles!
end;
Es scheint als ob WaitFor nicht die Geduld hat bis Close auch beendet ist. In diesem Fall kommt es zu einer AV-Exception. Wenn ich Close auskommeniere funktioniert alles normal...

Soll ich anstelle von WaitFor besser WaitForSingleObject verwenden?

Danke und Gruss

Tom

ste_ett 4. Jul 2006 13:22

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Gehört Close zu der Thread-klasse oder zu dem Process/ zuz der Klasse, die den Thread startet?

TomDooley 4. Jul 2006 13:28

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Close ist eine Funktion einer Hilfsunit, welche ausschliesslich im Hilfsthread verwendet wird.

Christian Seehase 4. Jul 2006 13:31

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Moin Tom,

wenn ich das richtig sehe, wird die While-Schleife verlassen, wenn der Thread auf Terminated läuft.
Auf was sollte WaitFor dann noch warten?

ste_ett 4. Jul 2006 13:37

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Zitat:

Zitat von Christian Seehase
Moin Tom,

wenn ich das richtig sehe, wird die While-Schleife verlassen, wenn der Thread auf Terminated läuft.
Auf was sollte WaitFor dann noch warten?


Wenn die While-Schleife durch ist, wird das Close() noch ausgeführ um aufzuräumen.
Der Hauptthread soll wohl noc hsolange wartenb, bis auch das fertig ist.

TomDooley 4. Jul 2006 13:49

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Zitat:

Wenn die While-Schleife durch ist, wird das Close() noch ausgeführ um aufzuräumen.
Der Hauptthread soll wohl noc hsolange wartenb, bis auch das fertig ist.
genau so! :-D

Christian Seehase 4. Jul 2006 14:09

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Moin Zusammen,

da habt ihr mich missverstanden:
WaitFor wartet u.a. darauf, dass Terminated = true ist.
Dies ist nach Verlassen der While-Schleife der Fall, so dass WaitFor nichts mehr hat, auf dass es warten muss. ;-)

TomDooley 4. Jul 2006 14:27

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
ok, das habe ich tatsächlich falsch verstanden. Ich bin eigentlich davon ausgegangen dass WaitFor wartet bis Execute beendet wird. Da dies offensichtlich nicht der Fall ist, ist auch das Verhalten plausibel.

Gibt es trotzdem eine Lösung für mein Problem?

Ich probierte übrigens auch das Close aus dem Hauptthread heraus auszulösen. Da aber unmittelbar anschliessend der Hilfsthread beendet wird, trat das Problem genau gleich auf:
Delphi-Quellcode:
begin
  SendCloseToHilfsthread; //Close wird in dem Fall noch in der While-Schleife ausgeführt
  Hilfsthread.Terminate;
  Hilfsthread.WaitFor;
  //alles andere freigeben
end;

Christian Seehase 4. Jul 2006 14:29

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Moin Tom,

Zitat:

Zitat von TomDooley
Gibt es trotzdem eine Lösung für mein Problem?

Kannst Du nicht eine andere Abbruchbedingung für die Schleife finden?

TomDooley 4. Jul 2006 15:21

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Hallo Chris

Ich denke das würde sich sicher finden lassen. Das heisst aber das ich Terminate und WaitFor gar nicht mehr verwende... Was ist denn überhaupt der Sinn dahinter??

Danke und Gruss

Tom

Christian Seehase 4. Jul 2006 15:36

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Moin Tom,

Zitat:

Zitat von TomDooley
Das heisst aber das ich Terminate und WaitFor gar nicht mehr verwende...

Wieso?
Du sollst ja nur für die While-Schleife eine andere Abbruchbedinung finden.
Danach wird Close Durchlaufen.

Anschliessend kann dann Terminated auf True gesetzt werden, bzw. wird die Execute-Methode dann ja beendet.
In Beiden Fällen sollte dann ja WaitFor "zuschlagen".

DerDan 4. Jul 2006 15:46

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Hallo,



ich hab grad mal in Classes.pas nachgesehen und wenn ich es richtig interpretiere hat

WaitFor

nichts mit dem Terminate / Terminated zu tun, sondern kehrt zurück sobald der Thread beendet ist.

Also sollte deine Geschichte eigendlich funktionieren!

.Terminate setzt nur das Flag Terminated, dass du ja richtig als Abbruch auswertest.


Welche Version von Delphi hast du denn? bzw hast du den Quelltextg von Classes.pas?

mfg

DerDan

KingIR 4. Jul 2006 15:47

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Zitat:

Zitat von Christian Seehase
...
WaitFor wartet u.a. darauf, dass Terminated = true ist.
Dies ist nach Verlassen der While-Schleife der Fall, so dass WaitFor nichts mehr hat, auf dass es warten muss.

Sicher? Sieht mir in der Classes.pas nicht so aus:
Delphi-Quellcode:
function TThread.WaitFor: LongWord;
{$IFDEF MSWINDOWS}
var
  H: array[0..1] of THandle;
  WaitResult: Cardinal;
  Msg: TMsg;
begin
  H[0] := FHandle;
  if GetCurrentThreadID = MainThreadID then
  begin
    WaitResult := 0;
    H[1] := SyncEvent;
    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, 0, 0, 0, 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;
  end else WaitForSingleObject(H[0], INFINITE);
  CheckThreadError(GetExitCodeThread(H[0], Result));
end;
{$ENDIF}
WaitFor wartet bis der Thread beendet ist (d.h. .Execute komplett abgearbeitet ist). Das kann (und sollte) bei gesetztem Terminated-Flag natürlich vorzeitig passieren, hat aber direkt nichts mit WaitFor zu tun, soweit ich das sehe. Im vorliegenden Fall ist die .Execute-Methode ja erst fertig, nachdem Close abgeschlossen wurde. :cyclops:

DerDan 4. Jul 2006 15:49

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Ich stimme dem KingIR völlig zu


Delphi-Quellcode:
else WaitForSingleObject(H[0], INFINITE)
ist der Teil durch den ein Subthread durchläuft

TomDooley 4. Jul 2006 16:08

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
Ich arbeite mit Delphi 5:
Delphi-Quellcode:
function TThread.WaitFor: LongWord;
var
  Msg: TMsg;
  H: THandle;
begin
  H := FHandle;
  if GetCurrentThreadID = MainThreadID then
    while MsgWaitForMultipleObjects(1, H, False, INFINITE,
      QS_SENDMESSAGE) = WAIT_OBJECT_0 + 1 do PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE)
  else WaitForSingleObject(H, INFINITE);
  GetExitCodeThread(H, Result);
end;

TomDooley 5. Jul 2006 12:28

Re: trotz WaitFor wird nicht gewartet bis Thread beendet ist
 
:wiejetzt: jetzt bin ich ein wenig verwirrt... Müsste meine Version jetzt doch funktionieren? Was mache ich dann trotzdem falsch?


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