Private Array verschwindet

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Private Array verschwindet

Beitrag von Rudolf »

Hallo,
habe bei einem Kunden das Problem dass private deklarierte Arrays zeitweise verschwinden. Die Variaben sind eindeutig definiert und plötzlich nicht mehr da, bekomme einen Runtime Error mit "Unknown variable". Bis jetzt ist das nur in einem Programm Modul passiert mit zwei unterschiedlichen Variablen in zwei unterschiedlichen Funktionen. Der Fehler ist auch nicht reprodzierbar, kommt in unregelmäßgen Abständen. Das Programmmodul ist sehr groß mit 16700 Zeilen, aber das dürfte keine Auswirkung haben. Der Kunde verwendet einen RDP Zugang, also am Arbeitsplatz Rechner kanns nicht liegen. Hat jemand so etwas schon gehabt ?
Grüße
Rudolf
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: Private Array verschwindet

Beitrag von ramses »

Rudolf

verwendest du mehrere Threads?
Valar Morghulis

Gruss Carlo
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Private Array verschwindet

Beitrag von Rudolf »

Hallo,
ja, aber in diesem Fall (hoffe ich zumindest) wird der Programmteil nicht mehrfach aufgerufen, werde aber zur Sicherheit hier noch eine Sperre einbauen.
Grüße
Rudolf
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: Private Array verschwindet

Beitrag von ramses »

Rudolf

wenn du mit Threads arbeitest würde ich als globale Variablen PUBLIC Variablen verwenden die du im Main() initialierst und auf alle PRIVATE komplett verzichten. Mit dieser Regel hatte ich nie mehr Probleme.

Cu Carlo
Valar Morghulis

Gruss Carlo
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Private Array verschwindet

Beitrag von Rudolf »

Hallo. Public geht leider nicht, nicht mal Static im Modul bei Multithreading. Nur Private werden in jedem Thread neu initialisiert
Grüße
Rudolf
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: Private Array verschwindet

Beitrag von ramses »

Hallo
du schreibst es gleich selbst: "Nur Private werden in jedem Thread neu initialisiert" .... und gelöscht .... Private's scheinen nicht völlig Thread-Save zu sein. Ich kann dir aus eigener Erfahrung nur empfehlen konsequent auf Private's in allen Programm Teilen gänzlich zu verzichten.....Ohne Ausnahmen....
Cu Carlo
Valar Morghulis

Gruss Carlo
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

Re: Private Array verschwindet

Beitrag von AUGE_OHR »

wie Carlo schon sagte sollte man bei Threads möglichst auf PRIVATE verzichten.

das "verschwinden" kenne ich übrigens aus meiner XppError Function wo ich den User (ID_USER) bei Fehler im Thread "nicht immer" habe.

nun stellt sich die Frage warum eine PUBLIC / PRIVATE und wie kann man das lösen ?
die Frage stellt sich ja auch bei altem Cl*pper Code wo noch gerne "viele" PUBLIC / PRIVATE verwendet wurden.

meine Lösung war damals "Summer93" (hiess wirklich so) was aus meine PUBLIC / PRIVATE eine Function machte.

Code: Alles auswählen

FUNCTION MyVar(xIn)
STATIC xValue
   IF PCOUNT() > 0
      xValue := xIn
   ENDIF
RETURN xValue
damit hat man "von überall" den Zugriff wie bei einer PUBLIC.

nun kann man mehrere solche Function zusammen in ein PRG schreiben und die einzelnen STATIC zu einer "Fieldwide" STATIC als Array.
bei 2-DIM Arrays verwende ich dazu "Namen"

Code: Alles auswählen

#xtranslate cKDNR                => Stack\[SP,1]
#xtranslate cARTNR               => Stack\[SP,2]
...
#xtranslate lGetTimeout          => Stack\[SP,99]

STATIC Stack := {}
STATIC SP    := 0
wenn man nun mit Threads arbeitet funktioniert es auch ... man erhöht einfach den "Zähler" (SP)
also schmeiss die PUBLIC / PRIVATE raus wo es geht und mache solche Function in einem PRG.
gruss by OHR
Jimmy
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: Private Array verschwindet

Beitrag von ramses »

Hallo Jimmy

nicht sollte, sondern grundsätzlich, egal wo und wie auf alle Private's verzichten! Regel 2
Die sind immer nur Ursache von Sorgen.
Diese Problematik z.B. auch von Clayton mit einer Funktion in der der Top-Down Lib gelöst.
Die Funktion draus zum lesen und schreiben solcher globaler Vars ist tdSetGlobal()


Code: Alles auswählen


STATIC aSysGlobal := {}    // ad hoc global values


******************************************************************************
*                           FUNCTION tdSetGlobal()
*
* A Get/Set function to manage an array of Global values.
******************************************************************************
function tdSetGlobal(cFlag,xNewValue,lAdd,lDelete,lReadOnly,lErrorLog )
LOCAL xOldValue,nEl

DEFAULT lAdd TO .F.,  lDelete  TO .F., lReadonly to .f., lErrorLog to .t.

IF valtype(cFlag) == "C" .AND. ! empty(cFlag)

   cFlag := lower(cFlag)   // force cFlag to lower case
   if valtype( xNewValue ) = "C"
      xNewValue := alltrim(xNewValue)
   endif

   ******* scan the array
   nEl := ascan(aSysGlobal,{|e| e[1]==cFlag})

   IF lAdd //  .AND. ! empty(xNewValue)    auch leere werte ansetzten     // add new element to array
      if nEl > 0 // aSysGlobal[nEl,3]
          logexeerror("Versuch vorhandener Para neu anzusetzten: TdSetGlobal - " + cFlag, .t.)
      else
          aadd(aSysGlobal,{cFlag,xNewValue, lReadOnly})
          *** return value is nil
      endif
   ELSE   // either retrieve, change, or delete
      IF nEl > 0   // found
         IF lDelete   // delete element
            if aSysGlobal[nEl,3]
               logexeerror("Versuch Readonly Para zu l”schen: TdSetGlobal - " + cFlag, .t.)
            else
              ******* remove specified element
               ARemove(aSysGlobal,nEl)
            endif
         ELSE   // either replace or retrieve, need to return existing value
            xOldValue := aSysGlobal[nEl,2]   // return existing value

            if lReadOnly .and. !aSysGlobal[nEl,3]   // Nachtr„glich Readonly Setzten wenn gewnscht
                aSysGlobal[nEl,3] := lReadOnly
            endif

            IF ! empty(xNewValue)   // replace specified value
               if aSysGlobal[nEl,3]
                   logexeerror("Versuch Readonly Para zu „ndern: TdSetGlobal - " + cFlag, .t.)
               else
                   aSysGlobal[nEl,2] := xNewValue    // replace value
               endif
            ENDIF
         ENDIF
      ELSE   // not found
        if lErrorLog
           logexeerror("Parameter ungltig: TdSetGlobal - " + cFlag, .t.)
        endif
        *** return value is nil
      ENDIF

   ENDIF   // lAdd
ENDIF   // cFlag

RETURN xOldValue
*                        End of FUNCTION tdSetGlobal()
******************************************************************************


Valar Morghulis

Gruss Carlo
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Private Array verschwindet

Beitrag von Rudolf »

Hallo,
ich habe so eine Funktion bereits die ich seit langer Zeit problemlos verwende. Die Idee von Jimmy ist interessant mit der Thread ID zusätzlich. Aber interessant dass es nur bei einem Kunden bis jetzt und nur auf einem Arbeitsplatz vorkommt.
Grüße
Rudolf
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: Private Array verschwindet

Beitrag von ramses »

Rudolf
nur auf einem Arbeitsplatz vorkommt
das könnte an der Konfiguration / Belastung des PC's liegen, so dass hier der Garbage-Collector von Xbase++ in anderen Abständen läuft und sich deshalb vorerst nur hier das Problem zeigt.
Cu Carlo
Valar Morghulis

Gruss Carlo
Antworten