Workspacelist() und Threads

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Workspacelist() und Threads

Beitrag von Manfred »

Hi,

wie muß man WorkSpaceList() benutzen um alle geöffneten DBF zu erhalten, egal in welchem Thread sie gerade geöffnet sind? Ich habe zwar etliches über Workspacelist hier gefunden, aber dazu nicht das, was ich meine verstanden zu haben.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Workspacelist() und Threads

Beitrag von georg »

Hallo, Manfred -


so wie ich die Dokumentation zu verstehe, akzeptiert WorkSpaceList() einen Parameter, der auf zwei WorkSpaces zugreifen kann:

- DB_ZEROSPACE
- DB_WORKSPACE

Wobei der Zugriff mit DB_WORKSPACE sich auf den aktuellen WorkSpace, d.h. den aktuellen Thread bezieht. Thread-übergreifend ist das m.E. (leider) nicht möglich.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Re: Workspacelist() und Threads

Beitrag von Manfred »

Den aktuellen Space bekomme ich ja dann wohl ausgelesen. Ich möchte aber jetzt eine Infofunktion bauen, in der ich ALLE geöffneten DBF anzeigen lassen kann, egal wo sie geöffnet sind. Und das hatte ich mir eigentlich einfacher vorgestellt. :roll:
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16508
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Workspacelist() und Threads

Beitrag von Martin Altmann »

Moin,
ist doch einfach, wenn Du z.B. mit Klassen arbeitest ;-)
Ich weiß ja nun nicht, ob das in dem aktuellen Fall so ist - aber wenn, kannst Du doch in Deiner Klasse eine entsprechende Methode implementieren. Dann brauchst Du nur noch diese für alle Deine instantiierten Klassen abrufen und hast die Infos.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Re: Workspacelist() und Threads

Beitrag von Manfred »

aha,

jetzt nochmal für Warmduscher.....
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Workspacelist() und Threads

Beitrag von georg »

Hallo,


die Kommunikation zwischen verschiedenen Threads ist sehr mühsam, wenn man solche Informationen braucht.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Workspacelist() und Threads

Beitrag von ramses »

@Manfred, wenn du mit "egal wo geöffnet" auch verschiedene Programme meinst geht das nur noch wenn du ADS einsetzt und alle DBF's über die ADSDBE öffnest, da kann dir dann das Servermodul Auskunft geben.

Cu Carlo
Valar Morghulis

Gruss Carlo
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Workspacelist() und Threads

Beitrag von georg »

Hallo,


mal etwas ausführlicher:

derzeit erlaubt es Xbase++ von Hause aus nicht, von einem Thread auf einen anderen zuzugreifen, geschweige denn Informationen über einen anderen Thread zu ermitteln.

Ein Lösungsansatz wäre:

a) das Standard-Thread()-Objekt durch ein eigenes zu ersetzen, das eine Liste der aktiven Threads (genauer: Thread-Objekte) in einer CLASS VAR führt;
b) beim Beenden eines Threads muss die CLASS VAR entsprechend aktualisiert werden;

Wenn nun Informationen aus einem anderen Thread abgerufen werden müssen, geht man die CLASS VAR durch und schickt an alle (ausser dem Thread, in dem das passiert, da hat man ja den Zugriff) ein User-Event an das Thread-Objekt. In jedem Thread muss der Event-Loop dieses User-Event abgreifen und entsprechend reagieren, z.B. indem eine Liste der aktiven Dateien im Workspace zurückgeliefert wird.

Es spricht nichts dagegen, dass es verschiedene User-Events gibt, von der Abfrage über ein dbCloseAll() bis hin zum Terminieren des Threads.

Wohl gemerkt, dies setzt immer voraus, dass in jedem Thread ein Event-Loop vorhanden ist, der die User-Events abfängt und überprüft. Wenn ein Thread z.B. nur im Hintergrund drucken soll, ist der leider aussen vor.

Ein kleines Beispiel: Aus einem Browse können einzelne Sätze zur Bearbeitung ausgewählt werden (die Bearbeitung erfolgt in einem eigenen Thread), und wenn die Änderung abgeschlossen ist, soll der Browse aktualisiert werden. Dateizugriffe habe ich in einer Klassge gekapselt, daher nicht wundern:

Code: Alles auswählen

	oBro:notify        := {|oBrowser, oHistfile, aData| BrowserRefresh(oBrowser, oHistfile, aData)}
Im Event-Loop prüfe ich dann auf dieses Event:

Code: Alles auswählen

	WHILE nEvent <> xbeP_Close
		nEvent := AppEvent(@mp1, @mp2, @oXbp)
		DO CASE
		CASE nEvent = xbeP_User_notify
			Eval(oBro:notify, oBro, oAudioHist, mp1)
(xbeP_User_notify ist meines Wissens selbst definiert.)

Da der Bearbeitungsthread eine Referenz auf das Browse-Objekt übergibt, wird das notify-Event so ausgelöst:

Code: Alles auswählen

      PostAppEvent(xbeP_User_notify, {aSortOrder, aPattern}, 0, oBro)
PostAppEvent() schickt das Event an den Event des Threads, zu dem oBro gehört. Ohne oBro würde das notify-Event im eigenen Thread landen.
Zuletzt geändert von georg am Sa, 25. Mai 2013 9:38, insgesamt 1-mal geändert.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Re: Workspacelist() und Threads

Beitrag von Manfred »

wie sangen schon die fanta4?

Es könnte alles so einfach sein, ist es aber nicht.

Ok, dann lasse ich diese Idee erstmal in der Schubslade verschwinden.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Workspacelist() und Threads

Beitrag von AUGE_OHR »

Manfred hat geschrieben:Es könnte alles so einfach sein, ist es aber nicht.
ist es doch ... wenn man ein entsprechendes Konzept hat ;)
"nachträglich" wird es schwer mit

Code: Alles auswählen

   aInfo := ThreadInfo( THREADINFO_TID      + ;
                        THREADINFO_TOBJ       )

   iMax := LEN(aInfo)
   FOR i := 1 TO iMax
       oThread := aInfo[2]
       AADD(aResult,{aInfo[1], oThread:Get_My_Workspacelist() })
   NEXT
denn ein "normaler" Thread hat ja keine Method Get_My_Workspacelist()

angenommen du hast eine Class "Kunden" und du willst per MDI mehrere Instanzen als Thread laufen lassen dann solltest du eine "eigene" Thread Class verwenden und die Method Get_My_Workspacelist() hinzufügen.

Code: Alles auswählen

PROCEDURE KundThread(cAction,nSeekRec,oDraw,oKunden)
LOCAL aThread  := SP_Thread()
LOCAL nLen     := LEN(aThread)
LOCAL oKundThread
...
   // did we have any Thread
   IF nLen > 0
      // is there any "KUNDEN" in it
      IF ASCAN( aThread, {|x| x[ID_WHO] == "KUNDEN" } ) > 0
         // find MAX position
         AEVAL( aThread, {|x| IF(x[ID_WHO] == "KUNDEN",;
                              aPos[2] := MIN(x[ID_POS][2], aPos[2]),;
                              NIL ) } )
      ENDIF
   ELSE
      ...
   ENDIF

   IF VALTYPE(nSeekRec) = "N"
      nPosi   := ASCAN( aThread, {|x| x[ID_REC] == nSeekRec .AND.;
                                      x[ID_WHO] == "KUNDEN" } )
      IF nPosi > 0
         setappFocus( aThread[nPosi][ID_OBJ] )
         RETURN
      ENDIF
   ELSE
      ...
   ENDIF

   IF lBig
      bBlock  := {|| YKUNDEN(AppDesktop(),NIL,aPos,aSize,aPP,.T.,cAction ,nSeekRec,oDraw),;
                             AppDesktop(),NIL,aPos,aSize,aPP,.T.,cAction ,nSeekRec,oDraw  }
   ELSE
      bBlock  := {|| YKUNDEN(oDraw       ,NIL,aPos,aSize,aPP,.T.,cAction ,nSeekRec,oDraw),;
                             oDraw       ,NIL,aPos,aSize,aPP,.T.,cAction ,nSeekRec,oDraw  }
   ENDIF

   oKundThread := MyThread():new()
   oKundThread:start( bBlock )
   SP_ThreadAdd({nSeekRec,cAction,aPos,"","KUNDEN"})
RETURN
die SP_* (Pseudo-) Function gehören zum Thread der ein Array verwaltet.

Code: Alles auswählen

FUNCTION YKUNDEN(oParent, oOwner, aPos, aSize, aPP, lVisible, cAction, nSeekRec,oDraw)
   ...
   oKunden := KundClass():New( oParent, oOwner, aPos, aSize, aPP, lVisible )
   ...
   oKunden:create()
   ...
   SP_ThreadObj(nSeekRec,cAction,oKunden,"KUNDEN")
   ...
   nEvent := xbe_None
   DO WHILE .NOT. ( lExit .OR. oKunden:lThreadExit )
      nEvent := AppEvent ( @mp1, @mp2, @oXbp ,100*60*10)
      ...
      DO CASE
      ...
      OTHERWISE
         oXbp:HandleEvent ( nEvent, mp1, mp2 )
      ENDCASE
   ENDDO
   ...
   oKunden:Hide()
   oKunden:destroy()
   oKunden := NIL

   nPosi   := ASCAN( aThread, {|x| x[ID_REC] == nSeekRec .AND.;
                                   x[ID_WHO] == "KUNDEN" } )
   IF nPosi > 0
      SP_ThreadDel(nPosi)
   ENDIF
   SELECT(oldSel )
   ...
klar muss man das Array von den Threads dann noch "aufräumen" wenn man den Thread schliesst.
gruss by OHR
Jimmy
Antworten