AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread und Indy - Programmabsturz

Ein Thema von Riese · begonnen am 1. Dez 2005 · letzter Beitrag vom 2. Dez 2005
Antwort Antwort
Riese

Registriert seit: 17. Nov 2005
16 Beiträge
 
Delphi 5 Standard
 
#1

Thread und Indy - Programmabsturz

  Alt 1. Dez 2005, 09:33
Hallo zusammen,

setze seit kurzem die Indy Komponenten ein.
Dabei vor allem die TIdTCPClient Komponente mit der ich einen Server kontaktiere.

Dabei liegt die Komponente auf einem Formular Form1.

Ich habe einen von TThread abgeleiteten Thread.

Im Thread lese ich mittels IdTCPClient1.ReadBuffer aus dem Client.

Je nach übermitteltem Kommando reagiere ich entsprechend im Thread.
Im Thread benutze ich dann zum Schreiben in ein Memo-Feld auf Form1 die Synchronize Methode.

Geht alles. Aber wenn ich mein Programm beende wird nur das Hauptformular Form1 beendet. Der Thread wird nicht beendet. Ich habe in OnFormDestroy (Form1) einen Aufruf myThread->Terminate drin.
Aber der funktioniert nicht da ich im Thread Terminated zwar abprüfe aber der Thread ja noch beim Einlesen von der IndyKompo hängt.
Denkt ihr dass ein TIdTCPClient-Timeout das Problem löst?

Manchmal kommt es auch vor, dass direkt nach dem Programmende der Thread abstürzt. Wie ist denn das mit Synchronize? Braucht man das beim Zugriff auf alle Komponenten auf dem Hauptformular oder nur bei den sichtbaren. Muss man also den Zugriff auf meine Form1.IdTCPClient1 Komponente auch in Syhronize kapseln?

Gruß und Danke
Riese
  Mit Zitat antworten Zitat
Benutzerbild von FriFra
FriFra

Registriert seit: 19. Apr 2003
1.291 Beiträge
 
Delphi 2005 Professional
 
#2

Re: Thread und Indy - Programmabsturz

  Alt 1. Dez 2005, 10:17
Das Problem hatte ich auch...

Ich habe es gelöst, indem ich zuerst im Hauptthread eine boolean Variable eingeführt habe, welche beim Threadstart auf True gesetzt wird. Der Thread selbst setzt diese beim beenden über synchronize wieder auf false. Im Hauptthread habe ich eine boolean Variable "IsClosing", welche onClose auf True gesetzt wird. Der Hauptthread muss dann beim onClose (nachdem IsClosing auf true gesetzt wurde) nur noch warten bis der Thread nicht mehr läuft. Dafür kann man eine While schleife verwenden
Elektronische Bauelemente funktionieren mit Rauch. Kommt der Rauch raus, geht das Bauteil nicht mehr.
  Mit Zitat antworten Zitat
Riese

Registriert seit: 17. Nov 2005
16 Beiträge
 
Delphi 5 Standard
 
#3

Re: Thread und Indy - Programmabsturz

  Alt 1. Dez 2005, 10:36
Hört sich gut an. Löst das Problem aber nicht.
Statt deiner Idee mit der Zusatzvariable könnte man ja auch einfach abfragen ob der Thread noch läuft, oder hab ich was falsch verstanden? (Wie das genau geht weiß ich grad net aber ich meine ich hätte es hier irgendwo gelesen?!)

der Thread hängt doch aber in der Methode ReadBuffer solange bis eine bestimmte Anzahl an Daten kommen. Kommen nun keine Daten, würde das System ja sich aufhängen in Deiner while Schleife, oder?

Gibt es keine SOFORT_THREAD_BEENDEN_METHODE?
  Mit Zitat antworten Zitat
Riese

Registriert seit: 17. Nov 2005
16 Beiträge
 
Delphi 5 Standard
 
#4

Re: Thread und Indy - Programmabsturz

  Alt 2. Dez 2005, 09:50
Nachdem bisher nicht sooo viele Antworten kamen will ich die Anfrage mal in ein paar kleinere Fragen zerteilen.

Das wichtigste zuerst (der Rest später):
Hat jemand Erfahrungen mit der Indy TCPClient-Komponente und da vor allem mit dem Timeout beim Lesen einer Verbindung. Wie macht ihr das, wie gross ist die Timeout Zeit. Was passiert falls die Timeout-Exception ausgelöst wird.

Gruß
Riese
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Thread und Indy - Programmabsturz

  Alt 2. Dez 2005, 11:20
Hi,
ich denke deine Fragen kann man nicht so wirklich pauschal beantworten. Sicherlich kommt es stark darauf an, was du für eine Anwendung (und Geduldsspanne) hast, wie große man die Time-Out Zeit wählt.
Wie man sich bei einer eintretenden Exception ist natürlich auch die Sache des Entwicklers. Du kannst versuchen den Kontakt wieder herzustellen, halt n mal oder du sagst dem Benutzer dass keine Verbidung hergestellt werden konnte (orientier dich einfach an dem was z.B. mail-clients oder Webbrowser machen).

Was dein Problem mit terminate angeht, so hast du doch die Schleife entworfen, die wartet, oder? Also du bekommst ja ein Ereignis wenn Daten ankommen und kannst dann mit den Daten irgendwas machen. Wenn ich dich richtig verstanden hab gehst du an der Stelle in eine Schleife und wartest bis xxx-Byte da sind. Dann musst du nur in dieser Schleife überprüfen ob terminated sich auf true geändert hat und ggf. die Schleife mittels break verlassen.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Riese

Registriert seit: 17. Nov 2005
16 Beiträge
 
Delphi 5 Standard
 
#6

Re: Thread und Indy - Programmabsturz

  Alt 2. Dez 2005, 13:27
Danke "Unwissender".

Also ich werde es wohl so machen, dass ich ein Timeout auf ein paar Sekunden setze. Dann würde ja die Exception ausgelöst und dort prüfe ich dann ab, ob der Thread Terminated ist.
Dort kann ich doch mit einem "return" (bin ja innerhalb OnExecute des Threads) sofort den Thread beenden, oder?
Bisher habe ich keinen Timeout in ReadBuffer so dass der Thread nie beendet wird.

Gruß
Riese
  Mit Zitat antworten Zitat
Riese

Registriert seit: 17. Nov 2005
16 Beiträge
 
Delphi 5 Standard
 
#7

Re: Thread und Indy - Programmabsturz

  Alt 2. Dez 2005, 13:30
Ach noch etwas was mich dazu auch brennend interessiert.
Mit Synchronize muss ich ja im Thread auf Komponenten der Form1 (u.a.) zugreifen.

Gilt das nur für die sichtbaren Eigenschaften oder zum Beispiel auch auf mein Indy-TCPClient der ja auch dort liegt.
Gibt das nur Probleme falls ich in Form1 auch darauf zugreifen würde (zum Beispiel TCPClient -Disconnect(!)) oder kann das immer zu Problemen führen bei der Ausführung des Programms?

Gruß
Riese
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#8

Re: Thread und Indy - Programmabsturz

  Alt 2. Dez 2005, 15:18
Ja, was soll ich sagen, du stellst echt gute Fragen

Wichtiger Grundsatz für gutes Nicht-Sequentielles Programmieren ist es, sperren so spät wie möglich setzen und so früh wie möglich entfernen. Dabei muss "wie möglich" auch wörtlich genommen werden.
Es ist gerade das Problem der Threads, dass du nicht sagen kannst ob es immer Probleme gibt oder nicht, kann die ersten 100000 mal gut gehen und beim nächsten nicht. Deshalb musst du es dir für dein (spezielles) Problem überlegen.

Du solltest immer dort synchronize einsetzen, wo es einen gleichzeitigen Zugriff geben kann und einer davon schreibend ist. Es ist unbendenklich beliebig viele Threads die selbe Variable lesen zu lassen, aber wenn einer ändert hast du ein Problem. Ganz wichtig ist es hier dann zu überlegen ab wo synchronized Sinn macht, beliebtes Beispiel: Zwei Threads A und B lesen x, erhöhen x um eins und schreiben es zurück. Nun sperrst du nur das Schreiben, dann kann es dazu kommen das A x liest, dann kommt b und liest x, beide erhöhen (in beliebiger Reihenfolge x), dann schreibt a x zurück (x = x+1) und jetzt kommt b ein weilchen nicht zum zug, A erhöht noch 10 mal x um 1 (x = x + 10) und nun kommt b wieder dran und nun ja, neun Erhöhungen gehen sofort verloren (b schreibt nur x+1 zurück).

Wie du hier vielleicht schon erahnen kannst, kann man schnell Dinge vergessen. Auf der sicheren Seite bist du, wenn du die ganze Methoden synchronzed setzt. Moment, merk gerade dass ich da was mit Java durcheinander bringe. Bei Delphi bekommst du ein Objekt (TCriticalSection) und musst so deine kritischen Stellen umschließen.

Um noch mal explizit auf deine Frage einzugehen, es ist egal was du änderst, es kann immer zu Problemen kommen wenn das gleichzeitig passieren könnte. Lesen kannst du hingegen aus beliebig vielen Threads gleichzeitig. Die Probleme die hier entstehen können haben nur was mit Fairness zu tun (wenn einer liest kann auch ein zweiter kommen und lesen, auch ein dritter, ... Kommt ein der schreiben will muss er warten, tja, wenn immer mehr lesende kommen wird halt nie geschrieben aber anderes Thema).
Ob eine Eigenschaft sichtbar ist oder nicht ist dabei vollkommen egal.
Wenn eine Komponente Thread-Safed ist, dann sollte ein setter dafür sorgen, dass nur ein Thread die Variable lesen bzw. schreiben kann. Ist eine Komponente nicht explizit als Thread-safed markiert, so kannst du nicht davon ausgehen dass es keine Probleme gibt.

Hoffe konnte helfen,

Gruß
  Mit Zitat antworten Zitat
Riese

Registriert seit: 17. Nov 2005
16 Beiträge
 
Delphi 5 Standard
 
#9

Re: Thread und Indy - Programmabsturz

  Alt 2. Dez 2005, 15:29
Wow!

Super ausführlich! Danke !!!
Jetzt habe ich das mit Synchronize verstanden. Es kann also auch beim Trennen einer Verbindung knallen wenn ein anderer Thread gerade auf Bytes wartet.

Gruß aus dem schönen Süddeutschland

Riese
  Mit Zitat antworten Zitat
Antwort Antwort


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 07:28 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