Habe wieder mal Thread-Problem [erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Habe wieder mal Thread-Problem [erledigt]

Beitrag von Wolfgang_B » So, 11. Mär 2018 11:24

Hallo,
ich melde mich wieder mal mit meinem alten Problem der Laufschrift ("Bitte warten ...."), die in einem eigenen Thread läuft. Das Thema hatten wir schon in dem Thread -> "Static Objekt in Funktion wird nicht gelöscht" ...

Das hat auch alles schön funktioniert, dummerweise habe ich es nur immer mit einer Auswertung probiert, die auch ein Ergebnis geliefert hat. Jetzt ist mir aufgefallen, daß die Laufschrift nur beim ersten Mal erscheint, d.h. ich starte eine Auswertung -> Laufschrift läuft. Beim nächsten Aufruf (vorher Funktion beendet) erscheint die Laufschrift nicht mehr. Warum? Beim Neuaufrufen der Funktion müßte doch der Thread wieder neu gestartet werden?

Code: Alles auswählen

FUNCTION LISTE_DRUCKEN()

  oThread2:Start( "MELDUNG", drawingArea, oThread2:threadID )

DO CASE

Code
.
.
Code

ENDCASE

MELDUNGSTOP(.T.)	

RETURN(NIL)

FUNCTION MELDUNG( drawingArea, id)																																// <-- LISTE_DRUCKEN() - (149)
  LOCAL xpos := 600
  
  //MsgBox("Meldung -> "+ALLTRIM(STR(id))  )
  // id -> nur zur Kontrolle des Threads
  // 
  oXbp := XbpStatic():new( drawingArea, , {xpos,10}, {500,25},{{XBP_PP_FGCLR, 13}, { XBP_PP_COMPOUNDNAME, "14.ARIAL Fett" } } )
  oXbp:create()
   
  DO WHILE !MeldungStop()
    IF xpos <=10
      xpos := 600
    ENDIF  
    oXbp:SetPos({xpos,10})
    oXbp:setCaption("Bitte einen Augenblick Geduld, Daten werden geladen ...")
    xpos-=3
    inkey(.2)
  ENDDO  
  
  oXbp:destroy()

RETURN( NIL )
// ENDFUNCTION MELDUNG()

FUNCTION MeldungStop(lSet)																																			// <-- LISTE_DRUCKEN() 3313 (.T. wenn Stopp)
STATIC lStop := .F.
IF PCount()>0
  lStop := lSet
ENDIF
RETURN lStop
// ENDFUNCTION MeldungStop(lSet)
Zuletzt geändert von Wolfgang_B am So, 11. Mär 2018 17:44, insgesamt 1-mal geändert.
Beste Grüße
Wolfgang

georg
Foren-Administrator
Foren-Administrator
Beiträge: 2121
Registriert: Fr, 08. Feb 2008 21:29

Re: Habe wieder mal Thread-Problem

Beitrag von georg » So, 11. Mär 2018 12:38

Hallo, Wolfgang -


das ist immer wieder das alte Problem mit Code-Ausschnitten, es fehlt hin und wieder was wichtiges ...

Wie initialisierst Du oThread2? Ist es eine Static-Variable, die Du nur einmal initialisierst, oder eine Local-Variable, die bei jedem Aufruf neu erstellt wird? Wie sieht die Definition weiterer Parameter des Threads aus, ich denke da an atEnd() und dergleichen?
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Re: Habe wieder mal Thread-Problem

Beitrag von Wolfgang_B » So, 11. Mär 2018 12:46

Hallo Georg,

ich verwende eine Local variable für den Thread:

Code: Alles auswählen

FUNCTION LISTE_DRUCKEN()

LOCAL oThread2  := Thread():new()

oThread2:Start( "MELDUNG", drawingArea, oThread2:threadID )

DO CASE

ENDCASE
MELDUNGSTOP(.T.)
ansonsten definiere ich nichts weiter. Beendet wird der Thread nach ENDCASE mit MELDUNGSTOP(.T.).

Funktioniert ja auch. Allerdings trotz neuem Aufruf der Funktion LISTE_DRUCKEN() und neuer Variable LOCAL oThread2 := Thread():new() nur einmal ...
Beste Grüße
Wolfgang

georg
Foren-Administrator
Foren-Administrator
Beiträge: 2121
Registriert: Fr, 08. Feb 2008 21:29

Re: Habe wieder mal Thread-Problem

Beitrag von georg » So, 11. Mär 2018 14:02

Hallo, Wolfgang -


wenn mir das passieren würde, dann würde ich in der Funktion Meldung einen Breakpoint definieren und sehen, was beim zweiten Durchlauf passiert.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Re: Habe wieder mal Thread-Problem

Beitrag von Wolfgang_B » So, 11. Mär 2018 14:18

so der dezente Hinweis, daß ich mich doch mal mit der Workbench beschäftigen sollte ... :?

Danke und Gruß
Wolfgang
Beste Grüße
Wolfgang

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7145
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Habe wieder mal Thread-Problem

Beitrag von Tom » So, 11. Mär 2018 15:59

MeldungStop(.F.) zwischendrin mal? :wink:

Edit: Das (MeldungStop()) ist Get-Set-Funktion. Du setzt sie auf .T., damit der Thread zum ersten Mal endet. Du musst sie wieder mit .F. besetzen, damit er beim zweiten Mal starten kann - ansonsten beendet er sich gleich wieder.
Herzlich,
Tom

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Re: Habe wieder mal Thread-Problem

Beitrag von Wolfgang_B » So, 11. Mär 2018 17:23

Hallo Tom,
das wars!!! Danke! Wie kommt man denn da drauf?

Was ich nicht verstehe, daß der Wert, der nirgends in einer Variable definiert ist und nur für die Übergabe gesetzt wird, nach Verlassen der Hauptfunktion (LISTE_DRUCKEN()) noch gültig ist ..

Gruß Wolfgang
Beste Grüße
Wolfgang

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7145
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Habe wieder mal Thread-Problem

Beitrag von Tom » So, 11. Mär 2018 17:31

Hallo, Wolfgang.

Freut mich!
Wie kommt man denn da drauf?
Weil mir das auch schon passiert ist. Diese Get-Set-Funktion arbeitet letztlich wie eine globale Variable (PUBLIC). Wenn Du sie ohne Parameter aufrufst, sagt sie Dir, auf welchem Wert sie gerade steht. Wenn Du sie mit einem Wert aufrufst, setzt sie diesen Wert und gibt ihn zurück. Mit "MeldungStop(.T.)" willst Du allen (!) Threads, die darauf reagieren, sagen, dass sie aufhören können. Wenn's wieder von vorne losgehen soll, musst Du den Schalter natürlich erst einmal wieder auf GO! legen. :wink:
Herzlich,
Tom

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Re: Habe wieder mal Thread-Problem

Beitrag von Wolfgang_B » So, 11. Mär 2018 17:43

nachvollziehbar. Da muß man aber erstmal draufkommen. Ich hätte nicht einmal gewußt, wo ich suchen soll ...

Noch einen schönen Sonntag

Gruß Wolfgang
Beste Grüße
Wolfgang

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11228
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von AUGE_OHR » So, 11. Mär 2018 18:17

Anmerkung :

mit MELDUNGSTOP(.T.) hältst du den Thread zwar an aber das Thread Object ist immer noch aktive :!:

also immer schön "aufräumen" wenn man mit Threads arbeitet denn das Thread Object wird nicht automatisch o:destroy()
gruss by OHR
Jimmy

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von Wolfgang_B » So, 11. Mär 2018 18:21

Hallo Jimmy,
wenn ich das richtig interpretiere, heißt das bei meinem Code, daß bei jedem Aufruf der Funktion eine Thread-Leiche übrigbleibt?

Gruß Wolfgang
Beste Grüße
Wolfgang

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7145
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von Tom » So, 11. Mär 2018 18:31

Quack.
Herzlich,
Tom

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 241
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 84169 Altfraunhofen

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von Wolfgang_B » So, 11. Mär 2018 18:32

Zusatzfrage: Wie kann ich feststellen, daß noch ein spezielles TreadObjekt aktiv ist?
Beste Grüße
Wolfgang

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11228
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von AUGE_OHR » So, 11. Mär 2018 19:31

Wolfgang_B hat geschrieben:
So, 11. Mär 2018 18:21
heißt das bei meinem Code, daß bei jedem Aufruf der Funktion eine Thread-Leiche übrigbleibt?
sorry ich hatte nur "wiederholt" im Kopf aber das machst du ja nicht so wie ich es meinte.

ein

Code: Alles auswählen

oThread:Destroy()
gibt es ja nicht

ich meinte wenn man

Code: Alles auswählen

o:SetInterval(nSec) 
benutzt muss man auch

Code: Alles auswählen

o:SetIntervall( NIL )
setzen um den Thread zu stoppen
gruss by OHR
Jimmy

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11228
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von AUGE_OHR » So, 11. Mär 2018 19:33

Wolfgang_B hat geschrieben:
So, 11. Mär 2018 18:32
Zusatzfrage: Wie kann ich feststellen, daß noch ein spezielles TreadObjekt aktiv ist?
siehe dir mal das an

Code: Alles auswählen

   aInfo := ThreadInfo( THREADINFO_TID      + ;
                        THREADINFO_SYSTHND  + ;
                        THREADINFO_FUNCINFO + ;
                        THREADINFO_TOBJ       )
   msgbox( VAR2CHAR(aInfo) )
gruss by OHR
Jimmy

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7145
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von Tom » So, 11. Mär 2018 21:53

Wenn die Routine im Thread endet, endet auch der Thread. Da muss nichts zerstört oder genilt werden. Ein einfaches RETURN genügt.
Herzlich,
Tom

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11228
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von AUGE_OHR » So, 11. Mär 2018 23:18

JA, sorry ...

ich hatte wie schon gesagt bei "wiederholt" an o:SetInterval() gedacht was Wolfgang aber gar nicht verwendet #-o
gruss by OHR
Jimmy

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 7145
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von Tom » Mo, 12. Mär 2018 9:35

SetInterval(x) hat eine ähnliche Funktionalität wie SetTimerEvent(). Es bewirkt, dass der Code(block), der via Start() einem Thread zugewiesen wurde, alle x Hundertstelsekunden ausgeführt wird. Wenn man also möchte, dass eine Synchronisationsfunktion einmal pro Sekunde aufgerufen (!) wird, verwendet man so etwas. Das ist aber kein Timer, der irgendwie innerhalb der aufgerufenen Funktion verwendet wird oder werden kann. Sie wird mit jedem Feuern des Timers erneut aufgerufen.

Und ich empfehle die Visite der Doku, um sich dort bei Gelegenheit mal auflisten zu lassen, welche Klassen "Destroy()" kennen. Das sind nämlich ausschließlich Klassen, über die XbParts im weitesten Sinne (und Fenster allgemein und Automation Objects als Sonderfälle) verwaltet werden. Nur da hat Destroy() überhaupt Sinn, weil nur da gebraucht wird, was Destroy() macht, nämlich Systemressourcen freigeben, die für ein Objekt angefordert wurden. Es wird aber nicht gelöscht. Man kann es durch ein erneutes Create() wiederbeleben. Für die Speichervariable, in der es verwaltet wird, ist all das komplett irrelevant.

Objekte sind letztlich Variablentypen. Wenn man sie mit NIL belegt oder schlicht eine Routine beendet, in der sie LOCAL definiert waren, sind sie weg. Das kann man auch mit einem Objekt machen, das zufällig gerade einen Thread verwaltet. Aber nötig ist das meistens nicht. Eigentlich nie. Code in einem Thread endet, wie Code generell endet. Es sei denn, man arbeitet mit bestimmten Eigenschaften, die Threads haben können (siehe oben).
Herzlich,
Tom

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11228
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Habe wieder mal Thread-Problem [erledigt]

Beitrag von AUGE_OHR » Mo, 12. Mär 2018 19:18

@Tom : JA du hast ja Recht ... ich hab wie schon gesagt an was anderes gedacht.

angenommen ich will eine Aktion starten wenn die App nicht innerhalb der Zeit reagiert.
ich starte also einen Thread vor der beabsichtigten Aktion.

wenn die Aktion nicht innerhalb einer definierten Zeit antwortet soll der Thread active werden und ihn raus werfen.
da die Aktion mehrfach passiert möchte ich die Variabel wiederverwenden

Code: Alles auswählen

STATIC oThread4 := NIL                                      // re-use it

   ERRORLEVEL( 5 )
   IF oThread4 = NIL
      oThread4 := Thread() :new()                           // start timeout thread
   ENDIF
   oThread4:setStartTime( SECONDS() + 5 + 5 + 5 )
   oThread4:start( "NEWF2", @lExit )

   BEGIN SEQUENCE
      // hier kann sich die App aufhängen
   RECOVER
      // hier recover
   END   
die Frage ist also wie beende ich den Thread
1.) wenn alles OK ist
2.) nach Abbruch
gruss by OHR
Jimmy

Antworten