Threads stürzen bei DLL Aufruf ab

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

Moderator: Moderatoren

Antworten
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Threads stürzen bei DLL Aufruf ab

Beitrag von ab-software »

Hallo,

ich habe das Problem das 2 meiner Threads abstürzen nachdem ich eine Funktions ausführe. Diese Function binde ich vorher über DLL Function ein. Jemand eine Idee woran das liegen könnte.

Vielen Dank schonmal
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo.

Wie wird abgestürzt (XPPERROR oder XPPFATAL)? Mit welchen Parametern? Wird vor oder nach dem Aufruf der Funktionen abgestürzt? Sind die Funktionen möglicherweise als STATIC FUNCTION deklariert?
Herzlich,
Tom
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Hallo,

es stürzen nur die Treads selbst ab , bzw. beenden sich. Die Functionen sind nicht static. Die Threads stürzen während der Funktion ab.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

Zur Problemeingrenzung schlage ich wie immer vor:

Code: Alles auswählen

procedure main
...
set alternate to debug.txt
set alternate on
set console off // wichtig bei reiner GUI Anwendung !
...
function DieAbstürzendeFunktion()
 
? "ThreadID",ThreadID(),seconds()
...
? "vor ..."
...
? "nach ..."
...
return ...
so müsste man feststellen können wo das Problem liegt.
Potentielle Probleme kommen von Public, Private, Static Variablen,
Annahmen zur Reihenfolge der Ausführung (diese stimmen fast nie bei mehreren Threads), Dateizugriffen in eine Datei ...

Dann vergleichen mit dem Ablauf im Hauptthread ...

Vielleicht hilft es ja ;-)
Gruß
Hubert
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Hallo,

konnte das Problem lösen, lag an einem Fehler in der DLL der dann die Threads hat mitabstürzen lassen.

Habe aber gleich noch ein Problem mit Threads, oder vielleicht verstehe ich da auch was noch nicht so ganz.

Wir sind gerade bei der Migration unseres alten Clipper Programmes nach Xbase, das geht bei uns leider nur immer Stück für Stück da auch das alte Programm parallel noch weiterentwickelt werden muss. Wir haben ein Xbase Programm das die ganze Zeit im Hintergrund läuft um Aufgaben zu erfüllen die vom Clipper Programm nicht mehr erfüllt werden können oder die wir schon umgestellt haben. Das Programm guckt (wenn es nicht gerade ein Programm ausführt) jede Sekunde in eine Datenbank ob vom Clipper Programm ein neuer Auftrag da ist.
Rufe ich jetzt über dieses Programm z.B. meinen Drucken Dialog auf funktioniert dort der Eventhandler nicht mehr / bzw. kaum noch. Die Fenster lassen sich nicht mehr schließen und reagieren nicht mehr auf Benutzerdefinierte Events die ich mittels PostAppEvent sende. Hat jemand eine Ahnung was das sein könnte?

Grüße
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

da braucht man mehr infos.

1. ruft das Überwachungsprogramm alle Sekunde z.B. mit TimerEvent die Überprüfung auf ? Wenn ja, könnte hier ein Mehrfachaufruf stattfinden.
2. Ist die Druckfunktion in einem eigenen Thread ?
3. Wenn die Oberfläche eines Programmes nicht mehr reagiert, weil z.B. eine lange For Next Schleife abgearbeitet wird oder die Datenbankabfrage ewig dauert, dann liegt das meist daran, dass keine Threads benutzt werden. Das BS gibt zwar Rechenzeit an jeden Thread, aber innerhalb des Threads wird nur eine Aufgabe erledigt. Wenn nun eine längere Schleife durchlaufen wird, kann nicht gleichzeitig die EventVerarbeitung aktiv sein. Daher sollte man solchen längeren Schleifen auslagern. Oder zwischendurch die Eventschleife aufrufen.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Beitrag von AUGE_OHR »

moin,
ab-software hat geschrieben: Das Programm guckt (wenn es nicht gerade ein Programm ausführt)
jede Sekunde in eine Datenbank ob vom Clipper Programm ein neuer
Auftrag da ist.
Die Frage ist wie das "timeout" erreicht wird ? nEvent == xbe_None ?
ab-software hat geschrieben: Rufe ich jetzt über dieses Programm z.B. meinen Drucken Dialog auf funktioniert dort der Eventhandler nicht mehr / bzw. kaum noch. Die Fenster lassen sich nicht mehr schließen und reagieren nicht mehr auf Benutzerdefinierte Events die ich mittels PostAppEvent sende. Hat jemand eine Ahnung was das sein könnte?
ohne den code zu sehen würde ich einfach mal tippen das ein
SLEEP() zum "timeout" in der AppEvent Schleife fehlt. Da durch
nimmt sich der 2st Thread die "ganze Zeit" sodas der 1st Thread
dann "träge" reagiert.

gruss by OHR
Jimmy
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Hallo,

also mein Thread ruft alle paar Sekunden (über set Inverfall) eine Funktion auf die dann je nach eintrag in der Datenbank das jeweilige Programm aufruft. Die Programme sind alle in Xbase DLL's ausgelagert um Updates beim Kunden so einfach wie möglich zu gestalten. Soweit ich weiß wartet der Thread auf die beendigung der Funktion und wird dann erst neu gestartet d.h. mehrfach aufrufe dürften nicht zustande kommen. Ich hatte die Druckfunktion auch schon in einem eigenen Thread konnte aber keinen Unterschied feststellen. Die Druckfunktion hat aber einen eigenen Eventhandler.
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

1. Laufen deine Threads ständig
2. oder werden über SetInterval jede Sekunde aufgerufen

zum 1.
bei jedem Thread kannst eigene Event-Schleife einsetzen.

zum 2.
Jimmy hat recht. du muss dann in den Funktionen, die im Thread ausgeführt werden, SLEEP() verwenden, damit deine Event-Schleife auch Rechenzeit bekommt.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

mit der Thread-Eventsteuerung habe ich mich noch nicht befasst, aber das Anlegen von mehreren Eventloops ist nicht unproblematisch.
Falls du wirklich 2 getrennte Threads mit je eigener Eventloop hättest, gäbe es keine Probleme mit der Anzeige. Offensichtlich wartet aber immer einer bis der andere beendet ist und bedient derweil sein eigenes Programm nicht mehr.

Ich habe in meinen Programmen (alles im Hauptthread) einige Druck-, Such-, Im- und Export Vorgänge in eigene Threads ausgelagert, die starten, verursachen keine Bildschirmausgabe und werden nach dem Ende einfach beendet. Eines davon überwacht z.B. ein Verzeichnis auf neue Aufträge, das dürfte deiner DBF Überwachung entsprechen.

Von früher her habe ich oft keine Threads eingesetzt, sondern die Eventloop regelmäßig aufgerufen:

Code: Alles auswählen

Hauptprogramm:
..
   doEventloop()
..
In einer Druck-/Verarbeitungsschleife
...
do while ...
    doEventLoop(0.01) // 1/100 Sekunde andere Events abarbeiten ...
    ...
...
*-----------------------------------------------------------------------------
FUNCTION DoEventLoop(nSeconds)               // For Next Schleifen unterbrechen und Events verarbeiten !
   local nBisSeconds, nEvent, mp1, mp2, oXbp

   DEFAULT nSeconds to 0                     // Standard ist endlose Ausführung
   mp1  := NIL                               // Wahrnungen verhindern
   mp2  := NIL
   oXbp := NIL

   nBisSeconds := seconds() + nSeconds

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp, nSeconds)
      do case
         case nEvent = xbe_None
            * nichts tun ist hier Standard
         case nEvent = xbeP_Keyboard .and. mp1 == xbeK_F1
                       * xbeP_HelpRequest erscheinen für jede Xbp Instanz, also zu oft !
                       MsgBox("Die Hilfe ist für dieses Programm noch nicht erstellt.")
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
      if nSeconds > 0 .and. nBisSeconds < seconds() // nur wenn keine endlose Ausführung
         exit
      endif
   ENDDO
return nil
Ich weiß jetzt nicht, ob ich das richtig verstanden habe, aber wenn das Hauptprogram der Threadsteuerung nur immer einen Auftrag erledigt, bis der nächste dran kommen kann, warum dann überhaupt eine Threadsteuerung ? Das aktive Programm wird aber solange keine eigenen Threads mehr abarbeiten können, wie die eigene Eventloop durch warten auf das Funktionsende blockiert ist.

Die Aufgabe müßte asyncron ablaufen und nur der Neustart blockiert werden (durch gobale Variable oder DBF Feld in AuftragsDBF ...), dann würde die Anzeige funktionieren. Oder deine Funktion kann obige Funktion aufrufen, aber bei getrennten Threads geht das glaube ich nicht.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

nochmals zu der Ausführung, bist du sicher, dass ein solcher Thread erst :interval 1/100-Sekunden nach dem Ende wieder den execute Block startet ? Ich hatte es immer so verstanden, dass er nach der Zeit die Ausführung startet, egal ob die letzte fertig war, ich bin mit nicht sicher, das hätte aber Auswirkungen.
Zuletzt geändert von brandelh am Mi, 26. Jul 2006 12:58, insgesamt 1-mal geändert.
Gruß
Hubert
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo,

ich habe ein Programm, was auf dem Server ständig läft und viele Aufgaben erledigt. Insgesamt laufen bei mir ständig 15 Threads, wobei eine1 davon Main ist und noch einer zu unterschiedlichen Zeiten zus. Threads startet, die nach ablaufen beendet werden. Der gleiche Thread sperrt zu bestimmten Zeiten die Ausführung anderer Prozesse.
Ich habe eine einzige Event-Schleife in Main. Die Ausgabe der Meldungen in ein MLE geht über eine Mehtode aus dem Hauptfenster, die mit SYNC deklariert ist, um die Meldungen nicht zu verlieren.
Bei kritischen Threads, die zuviel Prozessorleistung nehmen und andere Prozesse abbremsen, habe ich in den Schleifen immer SLEEP gesetzt.
Im Hauptfenster kann ich problemlos mit Menus und Unterfenstern arbeiten. Beenden der Threads wird über eine globale Variable gesteuert.
Gruß,

Andreas
VIP der XUG Osnabrück
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Hier mal der genauer Aufbau meines Programmes

Code: Alles auswählen


PROCEDURE MAIN()
   oThread := absThread():new()
   oThread:start("abs2Xbase", "")
   oThread:setInterval(100)

   // Eventhandler
RETURN

PROCEDURE abs2Xbase
  // Auftrag aus Datenbank laden
 
 IF cAuftrag == 'print'
   print(cParameter);
 ENDIF
RETURN 


FUNCTION print(cParameter)
  // Druckfunktion mit eigenem Eventhandler

RETURN lReturn 
Sobald ich versuche mit PostAppEvent zu posten wird dieses nicht berücksichtigt. Wo müsste ich das sleep einbauen?
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Code: Alles auswählen

PROCEDURE MAIN()
   oThread := absThread():new()
   oThread:start("abs2Xbase", "")
   oThread:setInterval(100)

   // Eventhandler
RETURN 
SetInterval ist zu spät gesetzt. Zu dem Zeitpunkt läuft dein Thread schon.

Richtig wäre:

Code: Alles auswählen

PROCEDURE MAIN()
   oThread := absThread():new()
   oThread:setInterval(100)
   oThread:start("abs2Xbase", "")
 

   // Eventhandler
RETURN 
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Beitrag von AUGE_OHR »

hi,
ab-software hat geschrieben:

Code: Alles auswählen

PROCEDURE MAIN()
...
   // 1st. Eventhandler 
RETURN 

PROCEDURE abs2Xbase  
....

FUNCTION print(cParameter)
  // Druckfunktion mit eigenem 2st. Eventhandler
RETURN lReturn 
Sobald ich versuche mit PostAppEvent zu posten wird dieses
nicht berücksichtigt. Wo müsste ich das sleep einbauen?
gerade der interessante Teil fehlt : Die Eventhandler !

also damit der 1st Eventhandler was bekommt musst du im
2st. Eventhandler ein SLEEP(xx) in deine Schleife mit einbaun.

mir ist auch nicht ganz klar wo dein PostAppEvent herkommt/
hinsoll ? An einen "Dialog" Keyhandler oder an einen Eventloop ?

grundsätzlich könnte man ja alle XbParts mit einem ":Keyboard"
versehen. Ich als alter Cl*pperraner nehme die Tastatur und bin
noch sehr "Masken" orientiert, also werden die xbeP_ Keyboard
jeweils über einen "oDlg:Keyboard" mit dem jeweiligem "Fenster"
(="Maske") verknüpft. Meine XbpPushbutton haben übrigen im
:activate Codeblock meinsten den Cl*pper "Tastencode" im
PostAppEvent() stehen.

Was für einen Event willst du senden ?
xbeP_ (Keyboard), xbeM_(Maus) oder xbeP_User +1 ?

also bitte zeigt uns deine Eventhandler und wo/was ausgelöst
oder ausgewertert wird.

wie fängst du in "abs2Xbase" eigendlich einen "zweiten" Aufruf ab ?
... wenn er in "print" > setInterval(100) verweilt käme ja dann
automatisch ein "weiterer" Aufruf ...

gruss by OHR
Jimmy
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Code: Alles auswählen

PROCEDURE Main()
  LOCAL ;
			nEvent  := 0    , ;
			mp1     := 0    , ;
			mp2     := 0    , ;
			oXbp    := NIL  , ;
			oTaskMen := NIL


  oThread := absThread():new()
  oThread:setInterval(100)
  oThread:start("abs2Xbase", "")

  oTaskBar := TaskBarIcon():New( xbeP_User + 30 ):Create()
  oTaskBar:AddIcon( 1, 1 , "ab-software abs2Xbase" )

  oTaskMen := XbpMenu():new( oTaskBar):create()
  oTaskMen:AddItem( { "Beenden" , { || PostAppEvent(xbeP_User + 1) } } )

  ErrorBlock( {|oError| ErrorHandler(oError) })

  DO WHILE nEvent <> xbeP_User + 1
	  nEvent := AppEvent( @mp1, @mp2, @oXbp )

     IF nEvent = xbeP_User + 30
	     IF mp1[2] = xbeM_RbUp
		    oTaskMen:PopUp(  oTaskBar, { mp1[3], mp1[4] } )
	     ENDIF
	  ENDIF

	  IF nEvent == xbeP_User + 1
		 oTaskBar:RemAllIcons()
	  ENDIF

     oXbp:handleEvent( nEvent, mp1, mp2 )
  ENDDO

RETURN

Code: Alles auswählen


PROCEDURE Callabs2Xbase()
  // Datenbank öffnen
  // Timestamp in eine Datei schreiben damit das ClipperProgramm weiß das wir noch laufen
 
 // Auftrag und parameter auslesen
 
 IF cProgramm == Upper(absBackup)
     absBackup()
 ENDIF
 
RETURN

Code: Alles auswählen

FUNCTION absBackup()
  
	 * Fenster erstellen
	 oDlg := dsDialog():new( AppDesktop(), , {370,320}, {400,230}, , .T.)
	 oDlg:taskList := .T.
	 oDlg:titleBar	:= .T.
	 oDlg:Title := "ab-software Datensicherung   "
	 oDlg:icon := 1                        // ab-icon
	 oDlg:maxButton := .F.
	 oDlg:minButton := .T.
	 oDlg:sysMenu := .T.
	 oDlg:EnableAutoScroll := .F.
	 oDlg:EnableStatusBar  := .F.
	 oDlg:AutoAccelerator  := .F.
	 oDlg:EnableFocusFrame(.T.)
	 oDlg:alwaysOnTop		:= .F.
	 oDlg:SetFocusFrame( GRA_CLR_GREEN,GRA_CLR_YELLOW,graMakeRGBcolor( {222,222,222} ) )
	 oDlg:SetQueryClose := {|| PostAppevent(xbeP_User + 2)}
	 // oDlg:SetQueryClose := {|| PostAppevent(xbeP_Close)}
	 oDlg:create()
	 oDlg:toTop()

 // Rest des Dialogs aufbauen
         * Schließen Button
  	 oClose := dsPushButton():new( drawingArea, , {10+50,105}, {125,70},  )
	 oClose:caption := "Daten einspielen"
	 oClose:create()

	 oClose:Activate := {|| PostAppEvent(xbeP_User +2) }
 
   * Eventloop
    DO WHILE nEvent <> xbeP_User +2
       * Eventhandler
       nEvent := AppEvent( @mp1, @mp2, @oXbp )
       oXbp:handleEvent( nEvent, mp1, mp2 )

       IF nEvent == xbeP_User +2
      	 oDlg:hide()
          oDlg:EndDialog()
       ENDIF

    ENDDO

  //DO WHILE nEvent <> xbeP_Close
  //   * Eventhandler
  //   nEvent := AppEvent( @mp1, @mp2, @oXbp )
  //   oXbp:handleEvent( nEvent, mp1, mp2 )

  //   IF nEvent == xbeP_Close
  // 	  oDlg:hide()
  //      oDlg:EndDialog()
  //   ENDIF
  //ENDDO

 
RETURN lReturn 
wie fängst du in "abs2Xbase" eigendlich einen "zweiten" Aufruf ab ?
... wenn er in "print" > setInterval(100) verweilt käme ja dann
automatisch ein "weiterer" Aufruf ...
nein da der Thread erst neugestartet wurde wenn der vorherige aufruf fertig abgearbeitet ist. Was er ja erst ist wenn der Dialog beendet wurde.

Also ich in dem Dialog versuche die Benutzerdefinierten Events zu posten reagiert der Dialog entweder garnicht oder beendet sich und alle anderen laufenden Threads ohne irgendeine Fehlermeldung.
Benutze ich das Standart xbeP_Close Event funktioniert der Dialog ohne Probleme.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

ich würde das ganze einfacher aufbauen ...

Code: Alles auswählen

procedure main
   memvar IsTreadRunning, IsTreadToKill, nNextTreadStart 
   public  nNextTreadStart := 0 // wird bei Ende von gestartetem 
                                   // Thread auf seconds()+1 gesetzt.
   public  IsTreadRunning := .f.  // oder über Funktion mit STATIC
   public  IsTreadToKill := .f. // diese Vars steuern den Tread ...
...
   DO WHILE nEvent <> xbeP_Close 
      nEvent := AppEvent( @mp1, @mp2, @oXbp, 100 )  // maximal 1 Sekunde warten
      * Events verbiegen kann man hier, aber aufpassen, SEHR KURZ halten !
      if nEvent # xbe_None  // ein Event ist eingetreten
         oXbp:handleEvent( nEvent, mp1, mp2 ) 
      endif
      if IsTreadRunning  // Thread läuft schon ...
         nNextTreadStart := nSeconds()+1
      else
         if nNextTreadStart <= nSeconds()
            IsTreadToKill := .f.
            oThread := absThread():new() 
            oThread:start("abs2Xbase", "") 
            // der Thread muss am Anfang  IsTreadRunning := .t. setzen !
         endif
      endif
      if Abbruchbedingung was weiß ich was 
         // der Thread muss diese Var überprüfen und sich beenden.
         // dabei muß er diese wieder auf .f. setzen.
         IsTreadToKill := .t.
      endif
  ENDDO 
... dies läuft alles im Hauptthread und ist schnell genug, dass nichts anbrennt...
Im aufgerufenen Thread selbst wird die Funktion aufgerufen und dort dann in einer eigenen eventloop alles verarbeitet. Da die Main aber nicht wartet und getrennt ist, wird die main beim Anzeigen nie behindert.

Innerhalb deines 2. Threads kann es nun passieren, dass das dortige Window durch eine lange Verarbeitungsfolge nicht aktualisiert wird, dann muss man dort in regelmäßigen Abständen appevent aufrufen, siehe hierzu meine schon gepostete Eventloopfunktion. Oder man lagert das dann auch in einen weiteren Thread aus.

Eventuell muss man noch syncronisieren oder weitere Flagvariablen (public oder static über funktion) einbauen, ich glaube aber nicht, dass ein Thread einem anderen etwas mit AppEvent senden kann.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Beitrag von AUGE_OHR »

hi,
ab-software hat geschrieben:

Code: Alles auswählen

FUNCTION absBackup()
   * Eventloop
    DO WHILE nEvent <> xbeP_User +2
       * Eventhandler
       nEvent := AppEvent( @mp1, @mp2, @oXbp )
       oXbp:handleEvent( nEvent, mp1, mp2 )

       IF nEvent == xbeP_User +2
          oDlg:hide()
          oDlg:EndDialog()
       ENDIF
//
// hier ein SLEEP(10) einbauen
// 
       SLEEP(10) 
    ENDDO
wie fängst du in "abs2Xbase" eigendlich einen "zweiten" Aufruf ab ?
... wenn er in "print" > setInterval(100) verweilt käme ja dann
automatisch ein "weiterer" Aufruf ...
nein da der Thread erst neugestartet wurde wenn der vorherige aufruf fertig abgearbeitet ist. Was er ja erst ist wenn der Dialog beendet wurde.
... hm ... das kann ich so nicht erkennen. im 2st. Thread wird der
Dialog bei "xbeP_User +2" geschlossen und sonst kommt der Event
nicht mehr vor ... ?

komisch ist auch die verwendung von "xbeP_User +2". geht das wirklich
"so", oder muss man nicht ein "#define xbeP_User +2 blabla" setzten ?
... auch "liest" es sich besser wenn man die Konstante dort stehen hat.


gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Jimmy,
AUGE_OHR hat geschrieben:hi,
komisch ist auch die verwendung von "xbeP_User +2". geht das wirklich
"so", oder muss man nicht ein "#define xbeP_User +2 blabla" setzten ?
alles was man mit #define setzt, wird vor dem compilieren wieder durch den Preprozessor ausgetauscht. Für Xpp ist es also egal ob man

Code: Alles auswählen

#define MyEvent xbeP_User +2
...
if MyEvent ...
oder

Code: Alles auswählen

if xbeP_User +2 ...
schreibt.
AUGE_OHR hat geschrieben: ... auch "liest" es sich besser wenn man die Konstante dort stehen hat.
genau deshalb und auch wegen der einfacheren Wartbarkeit (1 Stelle ändern und keine Tippfehler ...) sollte man define verwenden.
Gruß
Hubert
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Problem hat sich erledigt. Die Events kamen einfach im falschen Eventloop an. Habe einfach beim PostAppEvent den zusätzlichen Parameter für den Adressaten angegeben danach lief es.
Danke für euere Hilfe

Grüße
Antworten