Autor Beitrag
markusagb
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Do 16.02.17 19:00 
Hallo zusammen,

ich habe einen Thread erstellt und muss innerhalb dieser procedure FindComponent aufrufen, nur leider geht das im Thread nicht. Wie kann ich das realisieren? Danke schon mal an alle Profis!!

Source Code:

type
TServerMonitoringThread = class(TThread)
procedure Execute; override;
end;


procedure TForm1.TServerMonitoringThread.Execute;
var
Groupboxl: TComponent;
Rutine: Integer;
Begin
StreamNumbers:=(SettingsForm.ComboBox1.ItemIndex+1)*5;
For Rutine:=1 to StreamNumbers do
begin
Groupbox:=FindComponent('RzGroupBox'+IntToStr(Rutine));
If TRZGroupbox(Groupbox).Checked and (TRZGroupbox(Groupbox).Hint<>'') then
begin
.....
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Do 16.02.17 19:33 
user profile iconmarkusagb hat folgendes geschrieben Zum zitierten Posting springen:
procedure TForm1.TServerMonitoringThread.Execute;


Das kann so m.E. nicht funktionieren. Form1 gehört zur Klasse TForm1 und damit zum Main-/VCL-Thread.

Mit execute wird aber eine Ausführungsroutine der Threadklasse "TServerMonitoringThread" aufgerufen.

Ergänzung: Mag sein, daß meine vorige Ausführung falsch ist. Mit FindComponent suchst Du Komponenten des VCL-Threads. Damit greifst Du auf einen anderen Thread darauf zu (falls überhaupt). Das darf nach meinem Wissen nur über eine Synchronisation erfolgen.


Zuletzt bearbeitet von Delphi-Laie am Do 16.02.17 20:57, insgesamt 1-mal bearbeitet
markusagb Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Do 16.02.17 19:36 
Danke!!
Wie kann das aussehen?
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Do 16.02.17 19:49 
user profile iconmarkusagb hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann das aussehen?


Entweder, Du zeigst noch ein wenig mehr Quelltext und/oder die Fehlerausgaben, oder Du liest Dir durch, was in der von Delphi erzeugten Pascal-Datei steht, wenn Du Datei->Neu->Thread-Objekt (und dann einen Threadklassennamen vergeben, tatest Du evtl. schon) aufrufst.

Am besten auch Luckies Threadbibel und seine Beispiele anschauen.

Ergänzung: Nimm zumindest das "TForm1" vor TServerMonitoringThread.Execute weg. Und FindComponent kann m.E. nur in einer synchronisierten Prozedur aufgerufen werden.

2. Ergänzung: Delphi gibt das Grundgerüst auch mit Synchronisation schon vor:

Zitat:
type
test = class(TThread)
private
{ Private-Deklarationen }
protected
procedure Execute; override;
end;

implementation

{ Wichtig: Methoden und Eigenschaften eines Objekts in der VCL
können nur in einem Methodenaufruf mit SYNCHRONIZE
genutzt werden, z.B.

Synchronize(UpdateCaption);

und UpdateCaption könnte sein,

procedure test.UpdateCaption;
begin
Form1.Caption := 'Updated in einem Thread';
end; }

{ test }

procedure test.Execute;
begin
{ Plazieren Sie den Thread code hier }
end;


Zuletzt bearbeitet von Delphi-Laie am Do 16.02.17 19:54, insgesamt 2-mal bearbeitet
markusagb Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Do 16.02.17 19:50 
DANKE, ich werde mal weiter lesen!

=> Der Tipp mit der Thread Unit war super, ich habe den Thread ganz normal als eigene unit angelegt und alle "FindComponent" als "functions" in der Hauptunit angelegt. D.H. ich rufe aus dem Thread die function auf und damit ist das Problem gelöst.

DANKE!

Markus
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 18.02.17 20:44 
Ich hoffe mit Synchronisierung? Denn sonst scheint es zwar zu funktionieren, aber meistens gibt es dann irgendwann irgendwo unerklärliche Probleme.
markusagb Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Sa 18.02.17 21:43 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ich hoffe mit Synchronisierung? Denn sonst scheint es zwar zu funktionieren, aber meistens gibt es dann irgendwann irgendwo unerklärliche Probleme.


Nein, ich habe es direkt in den Thread gelegt, läuft seit 30 Std. ohne Probleme. Mal sehen was der Langzeit-Test sagt ...

Mit der Synchro wurde es genau so langsam - erst mit dem Thread läuft es jetzt richtig rund.
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Sa 18.02.17 23:51 
user profile iconmarkusagb hat folgendes geschrieben Zum zitierten Posting springen:
=> Der Tipp mit der Thread Unit war super, ich habe den Thread ganz normal als eigene unit angelegt und alle "FindComponent" als "functions" in der Hauptunit angelegt.


Das ist nicht nötig, und daran kann es deshalb m.E. nicht liegen. Threads kann man ohne Probleme in die Formularunit integrieren. Die Borland-Programmierer haben bei Anforderung eines neuen Thread-Objektes (genaugenommen einer neuen Threadklasse) wohl einfach deshalb eine neue Unit präsentiert, um diese "sauber" mit (ihrem) neuem Quellcode bestücken zu können. Beweis, daß Threads sich auch in der Formularunit wohlfühlen können, ist mein "Sortierkino", in das ich immer noch weitere Threadklassen integriere, und die alle in die Formularunit. Dort habe ich die Threadprogrammierung bis zum äußersten getrieben, jedenfalls arg in Richtung Windows-Qual. Und inzwischen läuft das auf meinen Computern auch stabil (sofern die Anzahl der erzeugten Threads nicht überhandnimmt).
markusagb Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: So 19.02.17 00:17 
Ja, aber es ging ja darum FindComponent in einem Thread aufzurufen..
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.02.17 14:54 
Da die VCL an sich nicht threadsicher ist, ist das schlicht nicht erlaubt. Dass das bei dir funktioniert im Moment, ist reiner Zufall.
markusagb Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: So 19.02.17 15:03 
Hallo,
auch wenn ich aus dem Thread eine procedure in z.B meiner Mainform aufrufe in der die FindComponent ausgeführt wird? Also die FC nicht im Thread sondern auf Form Ebene ausgeführt wird...?
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: So 19.02.17 15:38 
user profile iconmarkusagb hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
auch wenn ich aus dem Thread eine procedure in z.B meiner Mainform aufrufe in der die FindComponent ausgeführt wird?


Genau darum geht es doch - Du greifst auf visulle Komponenten aus einem Extrathread zu. Und das sollte / muß über Synchronize abgesichert werden. Schon die Borländer haben das doch schon eindeutig formuliert, ich wiederhole:

Zitat:
Wichtig: Methoden und Eigenschaften eines Objekts in der VCL können nur in einem Methodenaufruf mit SYNCHRONIZE genutzt werden


user profile iconmarkusagb hat folgendes geschrieben Zum zitierten Posting springen:
Also die FC nicht im Thread sondern auf Form Ebene ausgeführt wird...?


Auch dann. Diese Aufrufsverschachtelung ändert nicht daran, daß der Zugriff ungeschützt ist und bleibt und früher oder später zu Problemen führen wird / müßte.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.02.17 23:18 
Der Punkt ist eigentlich, dass du das ganze von der falschen Seite her angehst. Dein Thread greift auf den Status der Checkboxen zu. Dabei haben die ja ein Ereignis OnClick, in dem du auf eine Änderung des Zustands reagieren kannst.

Meine Vermutung ist, dass du damit steuerst was überwacht werden soll?

Wie wäre es, wenn du diese Information einfach korrekt synchronisiert an den Thread weitergibst? Dann musst du den Status erstens nicht pollen und zweitens nicht aus dem Thread auf die VCL zugreifen.

Dazu kommt, dass diese direkte Verbandelung der Logik im Thread mit der GUI (Thread kennt einzelne Komponenten der GUI) ohnehin nicht schön ist.