AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language For-Schleife im Thread wird nur einmal abgearbeitet
Thema durchsuchen
Ansicht
Themen-Optionen

For-Schleife im Thread wird nur einmal abgearbeitet

Ein Thema von Captnemo · begonnen am 6. Jun 2014 · letzter Beitrag vom 19. Aug 2014
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.136 Beiträge
 
Delphi 12 Athens
 
#11

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 6. Jun 2014, 21:54
Klingt logisch und einfach. Ist es sicherlich auch, wenn mal mit Threads viel Erfahrung hat. Leider muß ich da noch viel lernen und die Umsetzung fällt einem dann nicht immer so leicht.
Das mit Assigned(TThread(Sender).FatalException) hab ich grad mal gar nicht verstanden.
Schau dir mal das OnTerminate-Event des TThread an. Das ist wie das OnClick der TButtons und im Sender steckt die Instand des angeklickten Buttons, also in diesem Fall natürlich die Instanz des beendeten Threads.

Ich weiß ja nicht wie ud wo die die Instanz deines Threads gespeichert hast, aber das ist ja egal, da der Sender immer passt und man die Instanz somit auch da auslesen kann.
Man muß halt nur das TObject in den richtigen Typen casten, wenn man das verwendet.


Ergebnis: Du erstellst dir eine passende Methode, rufst darin das Syncronize und auf darin dann den genannten Code.
Und nun natürlich nur noch das Event dem Thread zuweisen.

Delphi-Quellcode:
procedure TDeineForm{oder dein TThread-Nachfahre}.MyThreadTerminate(Sender: TObject);
begin
  // TThread(Sender).Synchronize nehm ich jetzt mal nicht, da der Thread ja eigentlich schon beendet ist
  // und ich jetzt nicht genau weiß, ob was passieren könnte, auch wenn es vermutlich doch funktionieren könnte
  TThread.Synchronize(nil, procedure
    begin
      if Assigned(TThread(Sender).FatalException) then
        ShowException(Exception(TThread(Sender).FatalException), nil);
    end);
end;

PS: Wäre es nicht besser, wenn dein WriteLog im inneren prüft, ob es im Hauptthread läuft und sich notfalls selber synchroonisiert?
(oder notfalls einfach immer blind synchronisieren ... das Synchronize prüft das intern bestimmt auch selber nochmal)
Würde das Logging vereinfachen und so einige Codezeilen sparen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Jun 2014 um 21:58 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#12

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 6. Jun 2014, 21:57
Wird der TCPClient im Thread-Kontext erzeugt? Achtung: Im Thread-Konstruktor erzeugte Dinge sind nicht im Thread-Kontext, sondern in dem des Hauptthreads!!! Die meisten Komponenten, die irgendwie mit Sockets und ähnlichen WinAPIs hantieren sind oft nur in dem Kontext zu benutzen, in dem sie auch erstellt wurden. Ich bin damit schon mal mit SQL-Komponenten übel auf die Nase gefallen. Du musst diese in der Execute-Methode erstellen.

Dies ist zumindest eines der potenziellen Probleme die mir noch aufgefallen sind, das andere wurde schon genannt.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#13

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 7. Jun 2014, 10:43
Wird der TCPClient im Thread-Kontext erzeugt? Achtung: Im Thread-Konstruktor erzeugte Dinge sind nicht im Thread-Kontext, sondern in dem des Hauptthreads!!! Die meisten Komponenten, die irgendwie mit Sockets und ähnlichen WinAPIs hantieren sind oft nur in dem Kontext zu benutzen, in dem sie auch erstellt wurden. Du musst diese in der Execute-Methode erstellen.
Die Internet Direct (Indy) TCP Clientkomponenten können aus mehreren Threads verwendet werden, solange der Zugriffe threadsafe erfolgt. Ein Beispiel ist der Telnet Client "TIdTelnet" im Lib/Protocols Verzeichnis. Diese Klasse ist abgeleitet von TIdTCPClientCustom und startet einen Thread (TIdTelnetReadThread), der die vom Server gesendeten Daten empfängt. Die TIdTelnet Instanz wird zwar im Mainthread erzeugt, und aus dem Mainthread werden Befehle an den Server gesendet, aber aus dem ReadThread wird kontinuierlich auf den IOHandler der Komponente zugegriffen.

Möglicherweise besteht die Beschränkung (Verwendung nur im erzeugenden Thread) bei plattformgebundenen Komponenten wie ICS, die ein Windows Fensterhandle benötigen - aber mit ICS habe ich zuletzt 2008 kurz Kontakt gehabt.
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 7. Jun 2014, 11:13
Der Zugriff in der for-Schleife erfolgt eben nicht synchronisiert
Die erste Verwendung von frm_main.lv_waagen.Items.Count-1 ist nicht synchronisiert, die zweite schon.

Wobei diesesa andauernde Zugriff auf frm_main (und dann auch noch globale Variable ) sagen wir mal: potential zur Verbesserung bietet.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#15

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 10. Jun 2014, 08:18
Der Zugriff in der for-Schleife erfolgt eben nicht synchronisiert
Die erste Verwendung von frm_main.lv_waagen.Items.Count-1 ist nicht synchronisiert, die zweite schon.
Warum?

Wobei diesesa andauernde Zugriff auf frm_main (und dann auch noch globale Variable ) sagen wir mal: potential zur Verbesserung bietet.
Wie kann man denn besser innerhalb des Threads auf Variablen / Daten des Hauptthreads (oder möglichweise auch anderen Threads) zugreifen?

Ich kenne bisher nur die Möglichkeit Daten an den Hauptthread mit Synchronize sicher zu übergeben.
Geht das mit Funktionen auch? Ich kenne das nur mit procedure.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#16

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 10. Jun 2014, 10:26
Der Zugriff in der for-Schleife erfolgt eben nicht synchronisiert
Die erste Verwendung von frm_main.lv_waagen.Items.Count-1 ist nicht synchronisiert, die zweite schon.
Warum?
Weil du das so programmiert hast?
Delphi-Quellcode:
      FCS.Acquire;
      // nicht synchronisierter Zugriff auf eine VCL-Komponente
      for I := 0 to frm_main.lv_waagen.Items.Count-1 do
      begin
        Synchronize(
          Procedure
          begin
            // hier ist es synchronisiert
            frm_main.Writelog('Sende Register '+inttostr(i)+' von '+inttostr(frm_main.lv_waagen.Items.Count-1));
          end
        );
        FTCPClient.SendCmd('Register:'+frm_main.lv_waagen.Items[i].SubItems[2]+':@');
      end;
      FCS.Release;
Wobei diesesa andauernde Zugriff auf frm_main (und dann auch noch globale Variable ) sagen wir mal: potential zur Verbesserung bietet.
Wie kann man denn besser innerhalb des Threads auf Variablen / Daten des Hauptthreads (oder möglichweise auch anderen Threads) zugreifen?

Ich kenne bisher nur die Möglichkeit Daten an den Hauptthread mit Synchronize sicher zu übergeben.
Geht das mit Funktionen auch? Ich kenne das nur mit procedure.
Ab besten gar nicht, sondern man übergibt dem Thread die Informationen, die er zum Laufen braucht und der arbeitet das ab.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#17

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 10. Jun 2014, 17:48
Der Zugriff in der for-Schleife erfolgt eben nicht synchronisiert
Die erste Verwendung von frm_main.lv_waagen.Items.Count-1 ist nicht synchronisiert, die zweite schon.
Warum?
Weil du das so programmiert hast?
Ach so, jetzt hab ich verstanden, was Bernhard damit meinte. Der zweite Aufruf von frm_main.lv_waagen.items.count ist ja für meinen Programmablauf nicht kritisch und diente lediglich den Protokollzwecken.

Gut, ich sollte vielleicht die gesamte Schleife synchronisieren.

Delphi-Quellcode:
      FCS.Acquire;
      // nicht synchronisierter Zugriff auf eine VCL-Komponente
      for I := 0 to frm_main.lv_waagen.Items.Count-1 do
      begin
        Synchronize(
          Procedure
          begin
            // hier ist es synchronisiert
            frm_main.Writelog('Sende Register '+inttostr(i)+' von '+inttostr(frm_main.lv_waagen.Items.Count-1));
          end
        );
        FTCPClient.SendCmd('Register:'+frm_main.lv_waagen.Items[i].SubItems[2]+':@');
      end;
      FCS.Release;
Wobei diesesa andauernde Zugriff auf frm_main (und dann auch noch globale Variable ) sagen wir mal: potential zur Verbesserung bietet.
Wie kann man denn besser innerhalb des Threads auf Variablen / Daten des Hauptthreads (oder möglichweise auch anderen Threads) zugreifen?

Ich kenne bisher nur die Möglichkeit Daten an den Hauptthread mit Synchronize sicher zu übergeben.
Geht das mit Funktionen auch? Ich kenne das nur mit procedure.
Ab besten gar nicht, sondern man übergibt dem Thread die Informationen, die er zum Laufen braucht und der arbeitet das ab.
Ab besten gar nicht ist toll. Nur in meinem Fall nicht möglich. Er baut beim erzeugen eine TCP-Verbindung auf, die während seiner Lebensdauer erhalten bleiben muss. Und in dieser muss er Daten über TCP empfange und ans Hauptprogramm weiterleiten, bzw. dort proceduren Auslösen und umgekehrt auch Daten vom Hauptprogramm empfangen, die er dann über TCP zu seinem Verbindungspartner weiterleitet.
Möglicherweise geht das nur über Messages.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#18

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 10. Jun 2014, 18:00
Weiterleiten und empfangen hört sich gut an, dann mach das doch auch so.

Der Thread empfängt aber z.B. nicht, sondern greift lustig in die GUI und bedient sich.

Ein Control missbraucht man auch nicht als Datenspeicher, sondern als interaktives Element zum Anzeigen und Erfassen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.136 Beiträge
 
Delphi 12 Athens
 
#19

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 10. Jun 2014, 20:56
Ach so, jetzt hab ich verstanden, was Bernhard damit meinte. Der zweite Aufruf von frm_main.lv_waagen.items.count ist ja ...
Nicht ganz.

Die For-Schleife liest erst alles aus und speichert sich den End-Wert zwischen.
Die Start- und End-Werte werden also immer nur einmal zu Beginn abgerufen.
Manchmal läuft die Schleife "intern" sogar rückwärts, da ein Vergleich mit 0 einfacher ist und man sich dafür nicht den Endwert extra speichern muß.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: For-Schleife im Thread wird nur einmal abgearbeitet

  Alt 11. Jun 2014, 06:45
Zitat:
Manchmal läuft die Schleife "intern" sogar rückwärts, da ein Vergleich mit 0 einfacher ist und man sich dafür nicht den Endwert extra speichern muß.
Mit abw. Grenzen bis 0 (jz)
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 09:54 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