DbRelease(), DbRequest()

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

Moderator: Moderatoren

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21227
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 211 Mal
Danksagung erhalten: 71 Mal

Re: DbRelease(), DbRequest()

Beitrag von Manfred »

Es geht nichts über eine ordentliche Portion Missverständnis
Manfred hat geschrieben:Das ist ja alles schön und gut, aber das ist nicht die Lösung meines Problems. Ich bekomme das programmtechnisch nicht hin. Wie sieht sowas aus?

Code: Alles auswählen

dbRelease(nArea)
Thread starten
dbrequest(cAlias)
...
oder wie? Es klappt nicht bei mir. Irgendwas mache ich falsch.
Genau so klappt es doch. :roll:

Jetzt habe ich nur eine kleine Verständnisfrage: Wenn man Dbrelease() macht ist dann die DBF verschwunden für die Workarea, in der sie zuerst geöffnet wurde, oder erst wenn man DbRequest() macht? Ich frage deshalb, weil ich die DBF mehrmals an verschiedenen Stellen in dem Thread benötige, aber zu ganz unvorhergesehenen Zeiten. Also nur wenn sie upgedatet werden muß. Und das kann sein, muß aber nicht. Oder genügt es jedesmal ein DbRelease() - Arbeit - dbRequest() und alles ist dann in Ordnung, während der Zeit?
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: 16556
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 116 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: DbRelease(), DbRequest()

Beitrag von Martin Altmann »

Nach einem DbRelease() ist sie verschwunden aus der Workarea - ja.
Dein Ansatz sollte so - wie von Dir beschrieben - funzen.

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: 21227
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 211 Mal
Danksagung erhalten: 71 Mal

Re: DbRelease(), DbRequest()

Beitrag von Manfred »

Das ist Kappes. Ich benötige die im gesamten Thread. Also muß ich alle anderen Menupunkte dann sperren, damit ja keiner was anderes aufrufen kann. Weiterhin ist mir aufgefallen, dass der Selectbereich verloren geht (OK, ist eigentlich logisch). Über den spreche ich aber alle DBF an. Also muß ich den Request auch noch in bestimmter Reihenfolge machen, damit die Selectnummer erhalten bleibt. Also theoretisch ist diese ganze Technik für mein Problem nicht so optimal.

PS: Ok, das Problem mit dem Select hat sich erledigt. Den kann man ja vorher bestimmen über DbSelectArea() und der steht ja bei mir in dem Objekt selbst drin und das ist ja Public.

Hoffentlich knallt das nicht mal irgendwann in dem Kuddelmuddel.
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!!
manni1729
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 30
Registriert: Mi, 04. Jun 2008 14:18
Wohnort: Nordhessen

Re: DbRelease(), DbRequest()

Beitrag von manni1729 »

Ein Beispiel von mir,
die Hauptklasse wo das schreiben in die Status DBF geschieht.

Code: Alles auswählen

CREATE CLASS VIONServer
    PROTECTED:
    VAR nID

    EXPORTED:
    VAR cAdrWebShop
    VAR oFilInfo                            // Object fr FilialInfos und ProgrammInfos -> CLASS FilInfo

    VAR oSmpServer                          // Object fr Smartphoneserver wenn aus DLL aufgerufen

    METHOD init
    METHOD Destroy                          // Logdatei schliesen
    SYNC METHOD GenStatusDB                      // Status Tabellen erzeugen
    SYNC METHOD AddStatus                   // Status in Tabelle hinzufgen
    SYNC METHOD ScanStatus                  // Status auslesen und in Logdatei schreiben / anzeigen / Traceinfo
    SYNC METHOD LogDatei                    // Text in Logdatei schreiben
    SYNC INLINE METHOD AddLog(cText)                           // Eintrag in LogDatei mit VIONSrv():AddLog
        VIONSrv():oLog:AddLog(cText)
        return cText
    METHOD Stop                             // Server : stoppen / beenden  (bei Programm- Dienst Ende)
    METHOD Start                            // Server : starten            (bei Programm- Dienst Sart)
    METHOD Pause                            // Server : Pause / anhalten   (Aufruf aus Anpass, Vm2000 Reo, IsdnSend)
    METHOD Weiter                           // Server : Weiter / wieder starten  (Aufruf aus Anpass, Vm2000 Reo, IsdnSend)

    INLINE METHOD GenTranferObj()           // Transferobject fr internen Gebrauch
        RETURN Transfer():New()

    METHOD SendMail                         // Zentrale Stelle um Mails zu versenden (Server und VM2000)
    METHOD TraceInfo


ENDCLASS
Hier die Methode umd die DBF zu erzeugen

Code: Alles auswählen

// ----------------------------------------------------------------------------------------
METHOD VIONServer:GenStatusDB()
// ----------------------------------------------------------------------------------------
    LOCAL lRet := .F.
    LOCAL aDbf := {}
    LOCAL cDbServer := ::cVM2000Path+"VIONLOG"
    LOCAL nDel := 0

    //altd()


    // Status VIONLOG
    aDbf := {}
    aadd( aDbf, { "INFO",     "C", 100, 0 } )
    aadd( aDbf, { "TS",       "C", 13, 0 } )
    aadd( aDbf, { "PORT",     "N", 10, 0 } )
    aadd( aDbf, { "THREADID", "N", 10, 0 } )
    aadd( aDbf, { "THREADGES","N", 10, 0 } )
    aadd( aDbf, { "ERROR",    "N", 10, 0 } )
    aadd( aDbf, { "AKTFUNC",  "C", 30, 0 } )
    aadd( aDbf, { "LEVEL",    "N",  1, 0 } )
    aadd( aDbf, { "TYP",      "N",  1, 0 } )


    IF !FExists(cDbServer + ".DBF" )
        Risdbcreate( cDbServer, aDbf,"DBFNTX" )
        VIONSrv():oLog:AddLog("GenStatusDB():'"+cDbServer+"' neu erzeugt")

    else

        select 0

        USE ( cDbServer) EXCLUSIVE

        IF !neterr()
            select VIONLOG
            lRet := .T.
            IF ::lGui
                szeig("l”sche alte Logeintr„ge...",,,, {|| dbeval({||IIF( Ts2DateTime(VIONLOG->ts)[1]<=date()-1,(dbdelete(),nDel++) ,NIL ) }) })
            else
                dbeval({||IIF( Ts2DateTime(VIONLOG->ts)[1]<=date()-1,(dbdelete(),nDel++) ,NIL ) })
            ENDIF
            IF nDel > 0
                VIONSrv():oLog:AddLog("GenStatusDB(): loesche alte Datensaetze in '"+cDbServer+"' Anzahl: "+var2Char(nDel))

                IF ::lGui
                    szeig("Packe Logdatei...",,,, {|| dbpack()})
                else
                    dbpack()
                endif
            else
                VIONSrv():oLog:AddLog("GenStatusDB(): nichts zum loeschen gefunden in '"+cDbServer+"' Anzahl: "+var2Char(nDel))
            ENDIF
            CloseDBF("VIONLOG")
        else
            VIONSrv():oLog:AddLog("GenStatusDB(): kein exclusiever Zugriff zum loeschen moeglich '"+cDbServer+"' ")
        ENDIF
    ENDIF

    select 0
    if USEIND( cDbServer, .F. ,,cDbServer,,,,"DBFNTX" )
        select VIONLOG
        lRet := .T.
    endif
    DbRelease("VIONLOG")

return lRet
... und zum schreiben

Code: Alles auswählen

// ----------------------------------------------------------------------------------------
METHOD VIONServer:AddStatus(cInfo, nPort, nLevel, nTyp)
// ----------------------------------------------------------------------------------------
    LOCAL lRet := .F.
    LOCAL nAltBereich := select()
    LOCAL cStack := ""
    LOCAL nProgPos := 1
    LOCAL nPos := 1
    LOCAL aThreadInfo
    LOCAL nAktiv := 0
    LOCAL lTreadInfo := .F.

    DEFAULT nPort  TO 0
    DEFAULT cInfo  TO ""
    DEFAULT nLevel TO 1
    DEFAULT nTyp   TO 1

    FOR nPos := 1 TO 4
        cStack += Padright( procname( nProgPos ), 21,".") + "(" +str( procline( nProgPos ), 4) +") "
        nProgPos++
    NEXT
    IF lTreadInfo
        aThreadInfo := ThreadInfo( THREADINFO_TID+THREADINFO_TOBJ  )
        aeval(aThreadInfo,{|a|IIF( valtype(a[2])=="O",IIF( a[2]:active,nAktiv++,NIL) ,NIL )})
    ENDIF


    //altd()

    if DBRequest("VIONLOG",.t.)

        select VIONLOG
        IF NetAnh()
            replace VIONLOG->info        with cInfo
            replace VIONLOG->port        with nPort

            replace VIONLOG->threadId    with ThreadID()
            replace VIONLOG->threadGes   with nAktiv
            replace VIONLOG->ts          with UPDTIME
            replace VIONLOG->aktfunc     with procname(nProgPos)
            IF type("VIONLOG->level") == "N"
                replace VIONLOG->level     with nLevel
            ENDIF
            IF type("VIONLOG->typ") == "N"
                replace VIONLOG->typ     with nTyp
            ENDIF

            NetFrei()
            VIONLOG->(dbcommit())
            ::ScanStatus(nLevel)
        endif
        lRet := DbRelease("VIONLOG")
    endif
    select(nAltBereich)

return lRet
Die Methode AddStatus wird aus anderen Thread's aufgerufen die als Parameter die Klasse 'VionServer' übergeben bekommen.
Z.Bsp. so,

Code: Alles auswählen

CLASS ServerThread FROM Thread
    PROTECTED:
    VAR nSocket
    VAR nLastError

    EXPORTED:
    VAR nPort
    VAR lGui
    VAR oVIONServer
    VAR lAktiv
    VAR cName
    VAR oSignal
    VAR cIpAdr
    VAR bAltError

    METHOD init
    METHOD atStart
    METHOD execute
    METHOD atEnd
    METHOD stop



    METHOD logClient
ENDCLASS
 *************************************************************************************
 *************************************************************************************
// -------------------------------------------------------------------------------------------
METHOD ServerThread:init( nPort,cName, oVIONServer,oSignal )
// -------------------------------------------------------------------------------------------
    //LOCAL bAltFehler := errorblock( { | oError | FehlerChk( oError ) } )




    DEFAULT nPort      TO 0
    DEFAULT oVIONServer TO NIL
    DEFAULT cName      TO ""


    ::Thread:init(,"VION-S "+cName+" "+var2char(nPort))

    ::nPort      := nPort
    ::oVIONServer := oVIONServer
    ::cName      := cName
    ::nSocket    := 0
    ::lAktiv     := .F.
    ::oSignal    := oSignal
    ::nLastError := 0
    ::cIpAdr     := ""

RETURN self


// -------------------------------------------------------------------------------------------
METHOD ServerThread:atStart
// -------------------------------------------------------------------------------------------
    LOCAL cFehlertext := ""
    LOCAL cLocalAdr   := ::oVIONServer:cServerIP

    ::bAltError := errorblock( { | oError | ServerFehlerChk( oError,self,.t. ) } )
    ::oVIONServer:AddStatus("ServerThread  gestartet - ThreadID :"+var2Char(::threadID),::nPort,1)


    ::nSocket := SocketCreate( SOCK_STREAM, ::nPort,,,@::nLastError )


    IF ::nLastError <> 0
        // Fehler erkannt
        ::oVIONServer:AddStatus("ST: ERROR SocketCreate() - SNr: "+var2Char(::nSocket)+" E:"+var2char(::nLastError)+" "+SocketErrorText(::nLastError),::nPort,2)
    else
        ::oVIONServer:AddStatus("ST:SocketCreate() - SNr: "+var2Char(::nSocket),::nPort,1)
        IF ::nSocket <> 0
            ::lAktiv := .T.
            SocketListen( ::nSocket )
            ::setInterval(0)
        ENDIF
    ENDIF
RETURN self

// -------------------------------------------------------------------------------------------
METHOD ServerThread:atEnd
// -------------------------------------------------------------------------------------------
    ::nSocket := 0
    ::oVIONServer:AddStatus("ServerThread  beendet - ThreadID :"+var2Char(::threadID),::nPort,1)
    errorblock( ::bAltError )

RETURN self


So, das war jetzt ein Haufen Code, aber ich hoffe einigermasen verständlich!

Gruß Manni
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21227
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 211 Mal
Danksagung erhalten: 71 Mal

Re: DbRelease(), DbRequest()

Beitrag von Manfred »

Nächstes Problem,

wann hole ich denn die DBF wieder aus dem Zerospace raus, nachdem ich sie in dem Thread nicht mehr brauche und sie wieder zurückschiebe? Innerhalb des noch laufenden Threads? Kann doch nicht sein, oder? Da ist doch nicht bekannt, wo die DBF hin muß. Beende ich aber den thread mit :quit() geht nichts mehr.
Ich starte den Thread über einen Button. Wenn ich in dem Codeblock den Thread starte und direkt danach ein DbRequest mache, läuft das ja "parallel" und wird ausgeführt, bevor der Thread zuende ist. :confused2:
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
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21227
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 211 Mal
Danksagung erhalten: 71 Mal

Re: DbRelease(), DbRequest()

Beitrag von Manfred »

Ist jetzt alles vollkommen Wurst. Ich habe das Problem jetzt anders gelöst.
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!!
Antworten