![]() |
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:
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.
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; 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? |
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:
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
Synchronize()
Delphi-Quellcode:
vergessen hatte. Die ist mir vorher nie aufgefallen.
Synchronize()
|
AW: VST UI controls like should only be manipulated through the main thread
Welcher Code von dir wird denn im Thread aufgerufen?
|
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) |
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:
Delphi-Quellcode:
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. :)
Synchronize()
Du kannst alternativ auf
Delphi-Quellcode:
,
Queue()
Delphi-Quellcode:
oder
SendMessage()
Delphi-Quellcode:
benutzen.
PostMessage()
|
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:
Wie oben zu erkennen erzeug ich eine Instanz von TslImportFormTemplate innerhalb meiner MainForm.
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; 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. |
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:
um den Aufruf des Events und schon läuft das. Eventuell brauchst du eine kleine Helper Methode die du dann mit
Synchronize()
Delphi-Quellcode:
aufrufst sofern dein Event Parameter enthält.
Synchronize()
|
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. |
AW: VST UI controls like should only be manipulated through the main thread
Zitat:
|
AW: VST UI controls like should only be manipulated through the main thread
Zitat:
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:
im MainThread aufgerufen.
Synchronize()
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz