Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Threadfehler: Das Handle ist ungültig(6)
Flamefire - So 28.09.08 19:28
Titel: Threadfehler: Das Handle ist ungültig(6)
Ich bekomme obige meldung wenn ich versuche beim beenden meiner Anwendung einen Thread (bei dem FreeOnTerminate=true ist) so zu beenden:
Delphi-Quelltext
1: 2: 3:
| FCompareThread.Terminate; FCompareThread.WaitFor; FCompareThread:=nil; |
Der Fehler ist i-wo bei waitFor.
Hab aber keine Ahnung wie ich den beheben kann.
Delete - So 28.09.08 19:42
ähm...Zeig mal den ganzen Code
Flamefire - So 28.09.08 19:46
Mehr wird eigendlich nicht gebraucht.
Ich habe ne simple ableitung vom normalen TThread gemacht und create überschrieben um freeonterminate zu setzen
der thread durchläuft im execute ne ewig lange schleife (Datei-vergleich), die er bei terminated=true abbricht
aber ich denke ich hab ne lösung:
Delphi-Quelltext
1: 2: 3: 4:
| FCompareThread.FreeOnTerminate:=false; FCompareThread.Terminate; FCompareThread.WaitFor; FreeAndNil(FCompareThread); |
Lossy eX - Mo 29.09.08 09:06
Wenn du FreeOnTerminate gesetzt hast, dann wird der Speicher automatisch gelöscht. Dann brauchst du den nicht noch einmal per Hand freigeben. Wenn du weiß was da passiert wirst du merken, dass es sogar falsch ist den Speicher automatisch und direkt per Free freizugeben. Denn durch FreeOnTerminate wird nur der Speicher des Threads freigegeben. Aber der Inhalt des Speicher bleibt erhalten und die Instanz (FCompareThread) zeigt weiterhin auf diesen Speicher. Wenn du den Thread jetzt selber noch einmal mit Free freigeben willst, dann sieht das so aus ob der Thread noch existieren würde. Nur beim Löschen des Threads in Windows wird dann festgestellt "Hö. Moment mal. Den Thread gibs ja gar nicht mehr". Was wiederrum vollkommen berechtigt einen Fehler verursacht. Ist in etwas vergleichbar wie 2 aufeinander folgende Frees (nicht FreeAndNil). Denn das zweite Free würde auch noch mal versuchen die Instanz zu löschen.
Hoffe das hat dir den Hintergrund etwas erklärt. Also entweder FreeOnTerminate oder Free. Nie beides. Und wenn du FreeOnTerminate benutzen, dann solltest du aber keine Instanz von deinem Thread behalten. Denn alle Zugriffe die du machst können einen Fehler auslösen, wenn der Thread im Hintergrund schon gelöscht wurde. Zum Benachrichtigen bei der Beendigung eines Threads solltest du dann auch OnTerminate benutzen. Das entspricht auch eher dem Wesen der Threads.
Flamefire - Mo 29.09.08 10:12
ich benutze ja nie beides
nur darf man anscheinend waitfor und freeonterminate nicht zusammen benutzen
und ein onterminate kann ich nicht ganz gebrauchen, da ich unterscheiden will, ob ich den thread beendet habe, oder er zuende ist.
daher habe ich eine eigene prozedur
mit der lösung die ich gepostet habe funktionierts.
die refernez wird beim beenden immer auf nil gesetzt. daher klappt das auch
Lossy eX - Mo 29.09.08 10:34
Flamefire hat folgendes geschrieben: |
ich benutze ja nie beides |
Ups. Dann habe ich mich verlesen. :oops:
Flamefire hat folgendes geschrieben: |
nur darf man anscheinend waitfor und freeonterminate nicht zusammen benutzen |
Habe gerade in den VCL Quellen geschaut. Ja stimmt. Denn bei FreeOnTerminate gibt sich die Threadinstanz noch innerhalb des Threads frei und WaitFor wartet auf die Beendigung des Betriebssystemthreads. Die aber erst eintreten kann, wenn der Thread nicht mehr läuft. Und dann ist die Instanz schon längst weg.
Flamefire hat folgendes geschrieben: |
und ein onterminate kann ich nicht ganz gebrauchen, da ich unterscheiden will, ob ich den thread beendet habe, oder er zuende ist. |
Innerhalb des Threads weißt du ja ob abgebrochen wurde oder nicht. Wie wäre es da mit einem Flag? Wenn der Thread normal bis zum Ende durchgelaufen ist wird das Flag gesetzt und wenn er abgebrochen wird dann nicht. Bei OnTerminate bekommst du den Thread selbst als Parameter (TObject) und dort könntest du das Flag abfragen und gut. Nur eine Idee.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!