AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi TThread und TTimer - Free führt zu Exceptions
Thema durchsuchen
Ansicht
Themen-Optionen

TThread und TTimer - Free führt zu Exceptions

Ein Thema von DocE · begonnen am 10. Aug 2006 · letzter Beitrag vom 11. Aug 2006
Antwort Antwort
Seite 1 von 2  1 2      
DocE

Registriert seit: 25. Mär 2004
108 Beiträge
 
#1

TThread und TTimer - Free führt zu Exceptions

  Alt 10. Aug 2006, 21:40
Hallo zusammen!

Ich habe ein kleines Problem mit einem TThread.

In dem Thread erstelle ich dynamisch eine andere Komponente, die wiederum (u.a.) ein TTimer-Objekt enthält. Das stellt an für sich kein Problem dar. Gibt man jedoch die Komponente am Ende des Thread-Executes mit Free oder FreeAndNil frei, so kommt es zu folgenden Fehlermeldungen:

Mit Debugger:
Zitat:
Im Projekt TimerProject.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 00000000.
Lesen von Adresse 00000000'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
und

Zitat:
Im Projekt TimerProject.exe ist eine Exception der Klasse EOSError aufgetreten. Meldung: 'Systemfehler. Code: 1400.
Ungültiges Fensterhandle'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
Ohne Debugger:
Zitat:
Zugriffsverletzung bei Adresse 00000000. Lesen von Adresse 00000000.
und
Zitat:
Die Anweisung in "0x00000000" verweist auf Speicher in "0x00000000". Der Vorgang
"read" konnte nicht auf dem Speicher durchgeführt werden.
Der letzte Fehler wiederholt sich so lange, bis man den Prozess beendet (Taskmanager).

Das passiert auch, wenn der Timer niemals Enabled wurde.

Führt man das Free bzw. FreeAndNil mit Synchronized aus, kommt es zu keinem Fehler. Aber warum? Bzw. warum kommt es ohne Synchronized zu einem Fehler und wie kann man das verhindern?

Ich habe lange getüftelt, bis ich herausgefunden habe, dass der Fehler überhaupt an dem Timer liegt. Jetzt weiß ich aber nicht mehr weiter.

Meine einzige Vermutung wäre evtl. noch, dass dem Timer evtl. ein gültiges Fensterhandle fehlt???

Um das Problem besser nachvollziehen zu können, habe ich ein kleines Programm geschrieben, das auf das nötigste beschränkt ist. Der Quelltext ist hier angehängt.

Ich bedanke mich schonmal für eure Hilfe!


Grüsse
...Doc
Angehängte Dateien
Dateityp: zip timerthreadprojekt_149.zip (3,4 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#2

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 10. Aug 2006, 22:14
Warum nimmst du nicht den Destructor zum Freigeben von "MeineTimerKomponente".
Dann läuft es auch fehlerfrei ...


Delphi-Quellcode:
procedure TMyThread.MyFree;
begin
  // FreeAndNil(MeineTimerKomponente);
end;

destructor TMyThread.Destroy;
begin
  FreeAndNil(MeineTimerKomponente);
  inherited destroy;
end;
  Mit Zitat antworten Zitat
DocE

Registriert seit: 25. Mär 2004
108 Beiträge
 
#3

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 10. Aug 2006, 22:47
Hallo jensw_2000,

das funktioniert leider nur solange, wie Du den destructor falsch deklarierst. Ich gehe davon aus, dass Du diesen mit

destructor Destroy; eingebaut hast und nicht mit

destructor Destroy; override; In oberem Fall, wird dieser gar nicht beachtet, weshalb es scheinbar funktioniert. Das Objekt wird allerdings nicht freigegeben und belegt somit weiteren Speicher. Das macht zwar bei diesem kleinen Testprogramm nichts, im "echten" Programm ist das ganze doch um einiges speicherintensiver. Das Nicht-Freigeben stellt daher keine praktikable Lösung dar.

Mit unterer Implementierung kommt es leider zu den gleichen Fehlern, wie Anfangs erwähnt.

Das war also noch nicht des Rätsels Lösung...

Weiß noch jemand Rat?


Grüsse
...Doc
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#4

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 10. Aug 2006, 23:18
Zitat:
das funktioniert leider nur solange, wie Du den destructor falsch deklarierst
Stimmt leider. Sorry
  Mit Zitat antworten Zitat
TBx
(Administrator)

Registriert seit: 13. Jul 2005
Ort: Stadthagen
1.891 Beiträge
 
Delphi 12 Athens
 
#5

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 10. Aug 2006, 23:32
Hallo Doc!

Zitat von DocE:
Meine einzige Vermutung wäre evtl. noch, dass dem Timer evtl. ein gültiges Fensterhandle fehlt???
Nein das ist definitiv nicht das Problem.
In TTimer wir ein nicht sichtbares Fenster erstellt. Über dieses wird dann mit dem eigentlichen Timer, der aus Windows selbst kommt, komuniziert (mal vereinfacht gesprochen):

Somit spaltet TTimer einen eigenen Thread ab.

Und Aufrufe zwischen verschiedenen Threads müssen nun einmal synchronisiert werden.

Btw: In dem Destroy von TMeineKomponente kannst Du Dir das Zerstören des Timers imho schenken, da Du diesem Deine Komponente als Owner zugewiesen hast und das Free somit automatisch ausgeführt wird.
Im Destroy des TTimer wird auch vorher der Timer disabled.

Hoffe das bringt ein kleines bißchen Licht ins Dunkel (auch wenn andere das vielleicht ein bißchen besser erklären können)

Gruß

onlinekater
Thomas Breitkreuz
  Mit Zitat antworten Zitat
DocE

Registriert seit: 25. Mär 2004
108 Beiträge
 
#6

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 11. Aug 2006, 00:08
Hallo onlinekater,

Zitat von onlinekater:
Somit spaltet TTimer einen eigenen Thread ab.

Und Aufrufe zwischen verschiedenen Threads müssen nun einmal synchronisiert werden.
Heißt das, dass TMeineKomponente "synchronized" freigegeben werden muss, da TTimer ebenfalls einen Thread erzeugt?

Ich finde das ganze dennoch etwas unlogisch. Der Timer war nie Enabled, also aktiv... Wieso macht der plötzlich nach der Freigabe Probleme? Ein Free auf den Timer sollte doch eigentlich das ganze ordentlich beenden.

Soweit ich das überblicken kann, würde ich TTimer nicht als einen Thread beschreiben, sondern eher, als eine Komponente, die Windows-Botschaften ausliest und bei WM_TIMER das Ereignis auslöst. Das Auslesen von Windows-Botschaften passiert, meiner Meinung nach, nur im idle Zustand, also wenn nichts anderes läuft bzw. Application.ProcessMessages aufgerufen wird. Sehe daher keinen Synchronisationszwang. Es ist für mich einfach unverständlich warum der Timer nachdem er freigegeben wurde, weiter Timer-Ereignisse auslösen will, dies jedoch zu einem Fehler führt...

Zitat von onlinekater:
Btw: In dem Destroy von TMeineKomponente kannst Du Dir das Zerstören des Timers imho schenken, da Du diesem Deine Komponente als Owner zugewiesen hast und das Free somit automatisch ausgeführt wird.
Das Freigeben des Timers hatte ich vorher nicht im Destroy. War nur ein Versuch die Exceptions zu beheben -> brachte jedoch keinen Unterschied.

Noch eine Anmerkung zu den Fehlermeldungen: Diese kommen jeweils im TTimer eingestellten Intervall nach Freigabe der übergeordneten Komponente. Es scheint so, als lebe der Timer weiter, jedoch ohne eigentlich zu existieren.


Grüsse
...Doc
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#7

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 11. Aug 2006, 08:16
Vielleicht hast du dem VCL Thread vor dem freigeben deines Threads noch nicht genügend Zeit gelassen die aufgelaufenen WM_TIMER Botschaften aus seiner Warteschlange abzuarbeiten, weshalb nach dem freigeben durch dein Thread weitere Ereignisse auflaufen?
  Mit Zitat antworten Zitat
DocE

Registriert seit: 25. Mär 2004
108 Beiträge
 
#8

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 11. Aug 2006, 10:12
Hallo Muetze,

Zitat von Muetze1:
Vielleicht hast du dem VCL Thread vor dem freigeben deines Threads noch nicht genügend Zeit gelassen die aufgelaufenen WM_TIMER Botschaften aus seiner Warteschlange abzuarbeiten, weshalb nach dem freigeben durch dein Thread weitere Ereignisse auflaufen?
Eigentlich dürften überhaupt keine WM_TIMER Botschaften auflaufen...

Ich habe noch ein bißchen rumprobiert (einen "eigenen" TMyTimer geschrieben und anschließend auf den constructor, den destructor und eine leere WndProc reduziert) und herausgefunden, dass es an folgendem liegt:

Delphi-Quellcode:
destructor TMyAllocate.Destroy;
begin

  Classes.DeallocateHWnd(FWindowHandle);
  (...)
end;
Läßt man DeallocateHWnd weg, kommt es nicht mehr zu diesem Fehler, lediglich zu einem Speicherüberlauf nach vielen erstellten Threads, da das Window ja nicht mehr richtig freigegeben wird.

Weiß jemand, ob DeallocateHWnd einen Synchronized-Aufruf benötigt und evtl. warum?


Grüsse
...Doc
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#9

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 11. Aug 2006, 10:19
Hallo,

das Problem ist Folgendes:
Zitat von msdn:
Remarks
A thread cannot use DestroyWindow to destroy a window created by a different thread.
TTimer ruft im Destruktor MSDN-Library durchsuchenDestroyWindow auf. Das Erzeugen des Timers geschieht aber im Hauptthread beim Erstellen des Thread-Objekts. Deshalb existiert weiterhin ein Fenster mit einer Nachrichtenbehandlungsmethode eines TTimer-Objekts, welches aber nicht mehr existiert. Folglich kracht es.

Die Lösung ist simpel: Einfach den Timer erst in Execute erzeugen.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
DocE

Registriert seit: 25. Mär 2004
108 Beiträge
 
#10

Re: TThread und TTimer - Free führt zu Exceptions

  Alt 11. Aug 2006, 12:37
Hallo xaromz,

das scheint es zu sein.

Die Sache hat mich einfach nicht ruhen lassen, auch wenn der Fehler mit Synchronize behoben werden konnte. Jetzt ist auch klar warum. Durch Synchronize wird das ganze ja wieder im Hauptthread ausgeführt, somit ist Erzeuger und Freigeber des Windows wieder derselbe.

Vielen Dank!

Jetzt ist nur noch die Frage, was besser ist. Erzeugen und Freigeben der Objekte im Hauptthread (also im TThread.Create bzw. mit Synchronize) oder besser beides im Thread selbst (also im Execute).

Ich sehe da evtl. noch die Gefahr, dass es zu Problemen kommt, wenn der Thread "abstürzt". Oder ist das unbegründet?


Grüsse
...Doc
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz