Seite 1 von 1

Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 1:10
von AUGE_OHR
die Zeilen kennt wohl jeder

Code: Alles auswählen

   oPb := XbpPushButton():new() 
   oPb:create( , , {10,20}, {100,40} ) 
   oPb:activate:= {|| QOut( "Pushbutton A" ) } 
nun habe ich zum aktivieren bislang das benutzt

Code: Alles auswählen

PostAppEvent(xbeP_Activate,,,oPb)
wenn ich nun die Zeile mit dem Objeck "oPb" schon habe dann kann ich doch auch

Code: Alles auswählen

   IF VALTYPE(oPb:activate) = "B"
      EVAL(oPb:activate)
   ENDIF
schreiben ... oder ?
Die Frage wäre : in welchem Thread wird der Codeblock ausgeführt ?

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 8:06
von brandelh
schreiben ... oder ?
ja, habe ich schon gemacht, allerdings hat man dann KEIN Verhalten wie nach einem Klick auf den Button (Focuswechsel etc.)
Die Frage wäre : in welchem Thread wird der Codeblock ausgeführt ?
ich denke immer in dem, der den Code aufruft.

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 9:19
von georg
Hallo,


also, wenn der :activate Slot durch einen PostAppEvent() ausgelöst wird, dann wird der Code immer in dem Thread ausgeführt, in dem das Objekt erzeugt wurde (ich verwende eine vergleichbare Technik, um einen Browse in einem anderen Thread zur Aktualisierung zu zwingen), auch wenn das PostAppEvent() in einem anderen Thread ausgeführt wird. Das gilt aber nur, wenn die Anwendung mit /PM:PM compiliert wurde (siehe Eintrag PostAppEvent() in der Dokumentation).

Leider schweigt sich die Dokumentation dazu aus, wie sich Eval() in Bezug auf Multithreading verhält.

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 9:24
von brandelh
eval( {|| MyFunction() } )

macht nichts anderes als

MyFunction()

warum sollte das in einem anderen Thread ausgeführt werden, als dem der es aufruft ?

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 9:37
von georg
Hallo, Hubert -


wenn PostAppEvent(nEvent, mp1, mp2, oXbp) sich an den Thread wendet, in dem oXbp definiert wurde, dann ist die Frage von Jimmy schon berechtigt, da die Dokumentation dazu nichts aussagt.

Aber wahrscheinlich wird Eval(oPB:activate) in dem Thread ausgeführt, in dem Eval() ausgeführt wird, da hier nicht der Event-Loop ins Spiel kommt wie bei PostAppEvent().

Auf der anderen Seite steht das Objekt im Kontext eines anderen Threads, und eventuell kann nicht auf Resourcen zugegriffen werden, die im anderen Thread definiert sind.

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 10:15
von brandelh
Hallo Georg,

Bei PostApp() stimme ich dir zu, weil Event sogar Anwendungsgrenzen überschreiten können (wobei ich nicht weiß ob auch PostAppEvent() das kann),
können Sie auf jeden Fall Thread übergreifend tätig werden.

ich bezog mich auf diese Aussage:
Leider schweigt sich die Dokumentation dazu aus, wie sich Eval() in Bezug auf Multithreading verhält.
Ich denke dass dies klar ist, wenn eval einen codeblock ausführt (das ist ja nichts anderes als eine Funktion ohne Namen),
dann wird dieser Code genauso wie auch eine Funktion immer in dem aktuellen Thread ausgeführt, solange man nicht einem anderen Thread die Arbeit aufhalst.

Einfacher Test, wenn man diesen Code im Debugger Einzelschritt ausführt, springt man in den Codeblock (allerdings wird man dort meinst alles in einer haben ...) und wieder heraus.
Würde das ein einem anderen Thread ablaufen, dann dürft der aufrufende nicht warten bis man wieder zurückkommt.

Im Thread Beispiel der Kaffee Maschiene kann man sehr schön sehen wie sich Threads gegenseitig Infos teilen und aufeinander oder Zustände warten.
PS: die GUI selbst wird ja im Hauptthread erzeugt (also das Fenster etc.) aber die Aktuallisierungen laufen im GUI Thread ...

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Mo, 02. Feb 2015 23:56
von AUGE_OHR
hi,

Danke für eure Antworten.

Ich hatte extra o:activate gewählt weil es ein (bekanntest) Beispiel für einen Codeblock Slot ist.
auch hat o:activate ja keinen weiteren Parameter was die Sache vereinfacht.

Das Beispiel mit dem "Kaffee" Thread ist auch nicht das was ich mit "extern" meine denn innerhalb von Xbase++ Threads kann ich ja Parameter übergeben.

vielmehr meine ich Sachen wie

Code: Alles auswählen

   o:measureItem := {| nItem, aDims, self | ... }  
oder
   o:drawItem := {| oPS, aInfo, self | ... }
was ja im GUI Thread läuft ... und die beiden haben auch noch Parameter ...

Das Problem an dem ich gerade war betrifft

Code: Alles auswählen

XbpToolBar():buttonClick := {| oButton,uNil,self | ... } 
wo ich nicht wusste wie ich das Object oButton in ein PostappEvent() packen kann wenn ich den Codeblock aus einem String zusammenstellen soll.

Der o:buttonClick Codeblock Slot wird ja im "meinem" Source belegt aber ich kann den Codeblock ja in jedem (GUI) Thread EVALuieren.
solange es, wie in Huberts Beispiel, nur eine Function/Procedure "ohne" Rückgabe aufruft ist es wohl egal aber ich überlege ob es andere Situationen gibt wo das Prinzip nicht funktioniert ?

deshalb die Frage ob was dagegen spricht einen Codeblock Slot "gleich" zu EVALuieren statt ihn mit einem PostAppEvent() zu "aktivieren" ?

Re: Codeblock Slot : PostAppEvent() vs. EVAL()

Verfasst: Di, 03. Feb 2015 1:57
von brandelh
AUGE_OHR hat geschrieben: vielmehr meine ich Sachen wie

Code: Alles auswählen

   o:measureItem := {| nItem, aDims, self | ... }  
oder
   o:drawItem := {| oPS, aInfo, self | ... }
was ja im GUI Thread läuft ... und die beiden haben auch noch Parameter ...
Pablo hatte einmal erwähnt (und wohl auch Funktionen dazu), dass man manche Sachen auf den GUI Thread umleiten muss, ich habe das aber nie gemacht.