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 :mrgreen:
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