Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi VST UI controls like should only be manipulated through the main thread (https://www.delphipraxis.net/195862-vst-ui-controls-like-should-only-manipulated-through-main-thread.html)

Hobbycoder 2. Apr 2018 09:11

VST UI controls like should only be manipulated through the main thread
 
Moin,

ich bekomme bei einem VST welches auf einer eingebetteten Form liegt immer die im Threadtitel angegebene Exception.

Die Meldung ist bekannt, nur versteh ich zur Zeit nicht ganz, warum das in meinem Code auftritt.

Folgendes mache ich:

Ich erzeuge mir dynamisch einen TabSheet, auf welchem ich eine Form einbinde:
Delphi-Quellcode:
var
  page: TTabSheet;
  form: TslImportFormTemplate;
begin
  page:=TTabSheet.Create(pgcImports);
  page.Visible:=True;
  page.Caption:='Import von '+Name;
  page.PageControl:=pgcImports;
  form:=TslImportFormTemplate.Create(page);
  form.TabsheetHandle:=page.Handle;
  form.MainFormHandle:=Self.Handle;
  form.filename:=filename;
  form.Parent:=page;
  form.Show;
Meine Annahme war, dass die neue Form im MainThread läuft. Demnach sollte bei einem BeginUpdate und EndUpdate beim VirtualStringTree, welches auf der TslImportFormTemplate liegt, da auch unter dem MainThread laufen.
Ist aber scheinbar nicht so. Nur warum?

Sicherlich hat die TslImportFormTemplate ihr eigenes Handle, aber sollte doch so keinen eigenen Thread eröffnen? Oder liegt das was hinter, wes mir bisher verbirgt?

Ein Breakpoint im Quelltext des VST zeigt mir auch unterschiedliche ThreadId's.

Lasse ich BeginUpdate und EndUpdate weg, kann in TslImportFormTemplate die VST ganz normal mit Nodes bestücken. Nur ist das auf Grund der Anzahl dann natürlich vieeeeel zu langsam.

Kann mir das jemand erklären?

Aviator 2. Apr 2018 11:31

AW: VST UI controls like should only be manipulated through the main thread
 
Kommt die Meldung denn schon beim Erzeugen des Frames oder erst wenn du danach die Daten einfügen willst?

Falls es doch erst beim Einfügen der Daten kommt, musst du natürlich
Delphi-Quellcode:
Synchronize()
verwenden wenn du die Daten nicht im MainThread abrufst. Neuerdings (?) hat der VST eine solche Meldung eingebaut. Ich habe diese Meldung auch vor 3 Wochen gesehen als ich ein
Delphi-Quellcode:
Synchronize()
vergessen hatte. Die ist mir vorher nie aufgefallen.

jaenicke 2. Apr 2018 11:36

AW: VST UI controls like should only be manipulated through the main thread
 
Welcher Code von dir wird denn im Thread aufgerufen?

Hobbycoder 2. Apr 2018 11:40

AW: VST UI controls like should only be manipulated through the main thread
 
Erst mal danke für die Info.

Die Meldung kommt nur beim BeginUpdate, EndUpdate und auch beim Clear der VST.

Diese Methoden rufe ich in einer Procdure der Form auf, nicht in einem extra Thread. Dort besorge ich mir zwar die Daten ansich, aber die oben auf geführten Methoden und das erzeugen der Nodes mache ich erst, wenn dieser Thread beendet ist.
In der Mainform funktioniert das auch wunderbar.

Was mich wundert ist, dass die Meldung überhaupt kommt. Wenn ich in der Mainform und in meiner eingebetteten Form die ThreadID abfrage, bekomme ich die gleiche.
VST erhält aber in seinen Procedure wohl unterschiedliche :?

Und wenn ich das jetzt mal mit Synchronize versucht....ich meine mal gelesen zu haben, dass Synchronize im Mainthread zu Deadlocks führen kann.

(Ich habe mal in den entsprechenden Stellen ClearSelection und BeginUpdate das Assert auskommentiert. Dann läufts. Aber der Code ist nicht nur für mich, so dass es auch mit dem Orignal VST-Source laufen sollten. Hat ja sicher auch einen Grund, warum das da drin ist)

Aviator 2. Apr 2018 12:01

AW: VST UI controls like should only be manipulated through the main thread
 
Du schreibst, dass du die Daten erst dem VST zuführst wenn der Thread beendet ist. Woher weißt du denn das der Thread beendet ist?

Prüfst du in einem Timer irgendwie ob die Thread Ausführung abgeschlossen ist? Oder lässt du dir ein Event aus dem Thread feuern?

Zitat:

Zitat von Hobbycoder (Beitrag 1397869)
Und wenn ich das jetzt mal mit Synchronize versucht....ich meine mal gelesen zu haben, dass Synchronize im Mainthread zu Deadlocks führen kann.

Warum sollte
Delphi-Quellcode:
Synchronize()
zu Deadlocks führen? Es ist gerade dazu da, um einen Thread mit dem Mainthread zu synchronisieren und die Aktionen entsprechend dann erst auszuführen. Synchronize arbeitet blockieren, ja. Aber nur solange die Methode die du im Mainthread laufen lassen möchtest noch nicht abgeschlossen ist. Und für eventuell auftretende Deadlocks bist du selbst zuständig. :)

Du kannst alternativ auf
Delphi-Quellcode:
Queue()
,
Delphi-Quellcode:
SendMessage()
oder
Delphi-Quellcode:
PostMessage()
benutzen.

Hobbycoder 2. Apr 2018 12:48

AW: VST UI controls like should only be manipulated through the main thread
 
Ich lasse meine Form per Event vom Thread benachrichtigen.

Der Thread holt lediglich die Daten und legt sie in eine TobjectList ab. Erst nachdem erbeendet ist, wir und der Form eine Procedure aufgerufen:
Delphi-Quellcode:
procedure TslImportFormTemplate.BuildVST;
var
  I: integer;
Begin
  VST.beginupdate;
  Try
    VST.clear;
    For i:=0 to DatenObjectList.Count-1 do
      VST.addChild(nil, DatebObjectList[i]);
  Finally
    VST.Endupdate;
  End;
End;
Wie oben zu erkennen erzeug ich eine Instanz von TslImportFormTemplate innerhalb meiner MainForm.
Warum meint VST, dass es nicht in meinem MainThread läuft?

Und das ich mich im MainThread befinde, macht ja ein Synchronize mit sich selber an der Stelle gar keinen Sinn. Aber ich werde das mal ausprobieren.

Aviator 2. Apr 2018 12:53

AW: VST UI controls like should only be manipulated through the main thread
 
Doch genau das ist das Problem. Das Event wird gefeuert, befindet sich aber noch im Kontext des Threads. Mach mal ein
Delphi-Quellcode:
Synchronize()
um den Aufruf des Events und schon läuft das. Eventuell brauchst du eine kleine Helper Methode die du dann mit
Delphi-Quellcode:
Synchronize()
aufrufst sofern dein Event Parameter enthält.

Hobbycoder 2. Apr 2018 13:27

AW: VST UI controls like should only be manipulated through the main thread
 
Ja, hast recht. Ich kann‘s zwar grad nicht ausprobieren, aber ich glaube ich bin auf sowas schon mal reingefallen ;-)
Danke dir. Sollte es doch noch Probleme geben, melde ich mich hier noch mal.

jaenicke 2. Apr 2018 16:41

AW: VST UI controls like should only be manipulated through the main thread
 
Zitat:

Zitat von Aviator (Beitrag 1397872)
Warum sollte
Delphi-Quellcode:
Synchronize()
zu Deadlocks führen? Es ist gerade dazu da, um einen Thread mit dem Mainthread zu synchronisieren und die Aktionen entsprechend dann erst auszuführen.

Ja, aber in älteren Versionen von Delphi durfte man es nicht im Hauptthread aufrufen. Mittlerweile wird aber auch das korrekt behandelt, ebenso bei TThread.Queue und anderen solchen Funktionen. Wenn man also eine relativ aktuelle Version benutzt, braucht man da nicht mehr drauf zu prüfen, sondern kann es einfach aufrufen.

Aviator 2. Apr 2018 17:26

AW: VST UI controls like should only be manipulated through the main thread
 
Zitat:

Zitat von jaenicke (Beitrag 1397887)
Zitat:

Zitat von Aviator (Beitrag 1397872)
Warum sollte
Delphi-Quellcode:
Synchronize()
zu Deadlocks führen? Es ist gerade dazu da, um einen Thread mit dem Mainthread zu synchronisieren und die Aktionen entsprechend dann erst auszuführen.

Ja, aber in älteren Versionen von Delphi durfte man es nicht im Hauptthread aufrufen. Mittlerweile wird aber auch das korrekt behandelt, ebenso bei TThread.Queue und anderen solchen Funktionen. Wenn man also eine relativ aktuelle Version benutzt, braucht man da nicht mehr drauf zu prüfen, sondern kann es einfach aufrufen.

Ja das kann natürlich sein.

Allerdings hat der TE nirgends seine Delphi Version vermerkt (weder im Profil, noch im ersten Post). Und die Meldung vom VST, dass Aktionen im MainThread ausgeführt werden sollen, ist soweit ich weiß erst seit ein paar Versionen drin. Und seit ein paar Versionen wird auch nur noch bis XE3 unterstützt. Und ich behaupte jetzt mal, dass dieser Fehler in XE3 nicht mehr existent war, oder? Ich habe zwar lange Zeit mit XE3 programmiert, aber habe nie
Delphi-Quellcode:
Synchronize()
im MainThread aufgerufen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:13 Uhr.
Seite 1 von 2  1 2      

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