Seite 1 von 2
Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 00:52
von Daffy0815
Hallo Leute,
habe einen interessanten Effekt:
In einem Thread läuft eine Abgleichroutine welche unter Anderem in einem Fenster des Hauptprogramm via "SetGadgetText" einen Messwert aktualisiert.
Nun habe ich festgestellt, dass nicht jede "SetGadgetText-Anweisung" auch zur Ausgabe führt (was wohl daran liegt das der PC das nicht schafft).
Gibt es außer der Möglichkeit mit "GetGadgetText" abzufragen ob der Text auch "wirklich" aktualisiert wurde noch eine "elegantere", vielleicht sogar globale Möglichkeit zu prüfen ob Ausgaben in ein Fenster auch stattgefunden haben?
Gruß
Daffy
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 01:16
von STARGÅTE
Wäre schön wenn wir "diesen Effekt" auch sehen könnten, damit wir mehr dazu sagen können.
Fest steht, dass (die meisten) Aktualisierungen im Fenster erst dann ausgeführt werden, wenn ein WindowEvent() aufgerufen wurde. Davor wird der Wert nur "intern" geändert.
Das heißt, du kannst auch nicht mit GetGadgetText() den Text abfragen, da dieser ja den internen Wert ausgibt, der ja gesetzt ist!
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 01:25
von Daffy0815
@stargate
Also wie ich das machen soll das man den Effekt auch sehen kann ist mir, mal abgesehen davon ein Video vom Bildschirm zu drehen, ziemlich schleierhaft.
Danke für den Tipp das der neue Text nur intern gepuffert wird. Das erspart mir es auszuprobieren.
Was ist mit "ein WindowEvent() aufgerufen wurde" gemeint?
Etwas was vom System aufgerufen wird oder etwas was ich im Programm aufrufen kann?
Gruß
Daffy
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 01:34
von STARGÅTE
Daffy0815 hat geschrieben:Also wie ich das machen soll das man den Effekt auch sehen kann ist mir, mal abgesehen davon ein Video vom Bildschirm zu drehen, ziemlich schleierhaft.
Beispiel-Code?
Daffy0815 hat geschrieben:Was ist mit "ein WindowEvent() aufgerufen wurde" gemeint?
Du musst die PB-Fnuktion WindowEvent() aufrufen, damit das Fenster aktualisiert wird.
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 01:42
von ts-soft
STARGÅTE hat geschrieben:Du musst die PB-Funktion WindowEvent() aufrufen, damit das Fenster aktualisiert wird.
Ein bisschen genauer ist vonnöten, weil der Aufruf von WindowEvent() in dem Thread, wo er SetGadgetText nutzt,
wird nicht funktionieren!
Aber über die Grundlagen des Eventsystems in Windows und Beispiele für EventLoops gibt es hier ja zu hauf, müssen
wir hier nicht wirklich posten, wir sind ja auch nicht im Anfängerforum.
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 01:45
von Daffy0815
@Stargate
Beispielcode?!
Erfahrungsgemäß ist das Problem mit den "Beispielcodes" das die Probleme da leider in der Regel nicht auftauchen.
Für mein Problem in der Realität darzustellen benötigt man jede Menge Pneumatik-Klimbim, eine externe Hardware und last but not least so ca. 150 bar Druckluft
Das mit dem WindowEvent() Aufruf werde ich mal testen (aber erst Morgen macht nämlich einen irrsinnigen Krach mit der Druckluft).
Gruß
Daffy
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 02:13
von ts-soft
Code: Alles auswählen
Procedure Thread(dummy)
SetGadgetText(0, "blubb")
EndProcedure
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "")
StringGadget(0, 5, 5, 630, 25, "bla")
ButtonGadget(1, 5, 40, 80, 25, "start thread")
Repeat
Select WaitWindowEvent() ; erst mit erreichen dieses punktes, wird der Text geändert!
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 1
CreateThread(@Thread(), 0)
For i = 1 To 100000000
Next
EndIf
EndSelect
ForEver
Vom Thread aus kann man das nicht flashen!! Ereignisse können nur in dem thread abgearbeitet werden, wo
auch das Fenster erstellt wurde.
Und das setzen von SetGadgetText in ms Takt wird auch niemals zum Erfolg führen, bzw. könnte ja auch
keiner so schnell lesen
PS: Das ganze wurde mit Dir bereits mehrmals durchgekaut, wie es scheint immer noch ohne Erfolg.
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 02:15
von STARGÅTE
Tia Daffy0815, aber wie sollen
wir dann
dir bei einem "
Effekt" weiterhelfen der "
in der Regel nicht auftaucht"?
Um ts-softs Ergänzung noch etwas weiter auszuführen:
In dem Thread/Main-Programm, in dem das Window erstellt wurde, muss auch ein WindowEvent aufgerufen werden um alle Ereignisse abzuarbeiten und das Fenster zu aktualisieren.
Jedes SetGadget...() Funktion erzeugt nun selbst auch ein Event, was an das Fenster geschickt wird.
Das bedeutet u.a.: Du musst mindestens so oft ein WindowEvent im Ereignis-Loop aufrufen, wie in den Threads zusammen ein SetGadgetText() aufgerufen wurde.
Wenn du also aus sehr vielen Thread sehr schnell und oft SetGadgetText aufrufst, und "nicht so oft" WindowEvent(), kommen die Events nicht an, und andere werden u.u. sogar verschluckt oder hängen das Programm auf:
Hier ein Beispiel für diesen Effekt:
Code: Alles auswählen
Enumeration
#Window
#Gadget1
#Gadget2
EndEnumeration
Procedure MyThread(Gadget)
Protected I
Repeat
SetGadgetText(Gadget, Str(I))
I+1
;Delay(0)
ForEver
EndProcedure
OpenWindow(#Window, 0, 0, 800, 600, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
StringGadget(#Gadget1, 10, 10, 300, 20, "")
StringGadget(#Gadget2, 10, 40, 300, 20, "")
CreateThread(@MyThread(), #Gadget1)
CreateThread(@MyThread(), #Gadget2)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Select EventGadget()
EndSelect
EndSelect
ForEver
Beide Threads senden schneller als der MainLoop arbeiten kann Texte an die Gadgets, dabei kommt das eine Gadget "zu kurz"
(zumindest unter 2 Kernen, mehr Kerne müssten dann mehr Gadgets belasten)
Mach ich das Delay(0) rein, hat der MainLoop mehr Zeit
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 29.02.2012 02:27
von Daffy0815
@Stargate
Ja, ich denke das ist der Grund warum das Phänomen auftaucht.
Werde da morgen mal ein paar Änderungen einbauen.
Vielen Dank!
@ts-soft
Einerseits schätze ich Ihre äußerst kompetenten Antworten andererseits frage ich mich doch bei Ihnen warum diese dann häufig mit irgendwelchen "Spitzen gewürzt" sein müssen.
Geht das nicht auch ohne das?
Ich bin nun mal nicht PERFEKT!
Gruß
Daffy
Re: Ausgabe von SetGadgetText überprüfen
Verfasst: 01.03.2012 01:05
von Daffy0815
@Stargate
So, ich habe einige elementare Änderungen im Programm vorgenommen.
Die komplette Verarbeitung des Registerempfangs inklusive Schnittstellenringpuffer befindet sich nun in einem Thread.
Die Timer, Messroutinen / Einstellroutinen haben ebenfalls eigene Threads bekommen.
Die Rechenzeitverteilung zwischen Hauptprogramm und den Threads verläuft über Delay-Anweisungen und ist so eingestellt, das immer genug Zeit bleibt um die Werte in den Bildern darzustellen.
War also goldrichtig Ihre Analyse!
Ideal wäre allerdings wenn man den Threads einzeln eine feste Laufzeit zuteilen könnte (Zeitscheibe) nach deren Ablauf sie unterbrochen werden und dann der nächste Thread Rechenzeit bekommt.
Zu "Fuß" könnte man das sicher machen oder hat Windows so etwas schon eingebaut?
Gruß
Daffy