Seite 1 von 1

Thread und Frax

Verfasst: Do, 05. Dez 2013 15:28
von Werner_Bayern
Servus,

habe ich das richtig verstanden, dass Frax nicht thread-safe ist, weil init und destroy direkt wirken?

Bei mir knallt es, wenn der 2. Report geschlossen wird, wohl weil das destroy ins Leere geht, obwohl das 2 saubere Threads sind:

Code: Alles auswählen

   oFrax := frReportManager():new("FRSyst.dll")
   oFrax:SetIcon(4)
   oFrax:SetTitle("Abrechnung Konto")
   oFrax:SetUserDataSet("Daten", "Datum;Buchungstext;Konto;Soll;Haben;Brutto;Belegnr;Saldo",;
   {||I := 1}, {||I := I + 1}, {||I := I - 1}, {||I > Len(aDaten)}, ;
   {| cFeld | aDaten[i, ascan({"Datum", "Buchungstext", "Konto", "Soll", "Haben", "Brutto", "Belegnr", "Saldo"}, cFeld)]})
   oFrax:LoadFromFile("kontenabrechnung.fr3")
   oFrax:ShowReport()
   oFrax:ClearDatasets()
   oFrax:DestroyFR()

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 15:48
von brandelh
was passiert wenn du das destroyFR weg läßt ?

Eigentlich dürfte ein destroy nur das eigentliche oFrax zerstören, vermutlich ist die DLL Referenz nicht sauber umgesetzt.
Allerdings müsste es dann beim nächsten Zugriff knallen und nicht erst beim nächsten destroy.

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 16:08
von Werner_Bayern
korrekt, dann knallt es mit gleicher Fehlermeldung beim nächsten Aufruf, sobald 1x ein betroffener Thread beendet wird. Wird kein thread beendet, würde es gehen. :)

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 16:13
von Koverhage
Ich würde vermuten das es hieran liegt
oFrax:ClearDatasets()

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 16:26
von Werner_Bayern
Koverhage hat geschrieben:Ich würde vermuten das es hieran liegt
oFrax:ClearDatasets()
Nein, das hatte ich nur reingemacht aufgrund eines älteren Hinweises hier in diesem Forum.

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 16:28
von brandelh
wenn die DLL als solche nicht threadsave ist, dann muss man den gleichzeitigen Aufruf verhindern.
Solange nur Reports generiert werden, könnte man eine Schleife generieren, die die Reports erstellt - also eine Reportqueue.

Ist das Xbase++ code der knallt oder in der DLL ?

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 16:35
von Werner_Bayern

Code: Alles auswählen

Xbase++ Version     : Xbase++ (R) Version 1.90.355
Betriebssystem      : Windows Vista 06.00 Build 06002 Service Pack 2
------------------------------------------------------------------------------------------
oError:args         :
          -> VALTYPE: C VALUE: _DLL  xìV¤ u
          -> VALTYPE: N VALUE: 0
oError:canDefault   : N
oError:canRetry     : N
oError:canSubstitute: J
oError:cargo        : NIL
oError:description  : Interne Datenstrukturen beschädigt
oError:filename     : 
oError:genCode      :         41
oError:operation    : dllExecuteCall
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :          5
oError:subSystem    : BASE
oError:thread       :          4
oError:tries        :          0
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Aufgerufen von FRREPORTMANAGER:FRNOTIFYERROR(1206)
Aufgerufen von (B)FRREPORTMANAGER:SHOWREPORT(1300)
Aufgerufen von FRREPORTMANAGER:SHOWREPORT(1302)
Aufgerufen von KONTOAUSG(430)

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 18:02
von Lewi
Hallo!
oFrax:DestroyFR() führt zwangsläufig zum Entladen der Frax-DLL.

Eventuell hilft eine Klassenerweiterung der Klasse "FrReportManager()" um eine Methode "DestroyReport()"

Code: Alles auswählen

METHOD frReportManager:DestroyReport()
   ::PrintOptions := NIL
   ::PreviewOptions := NIL
   ::EngineOptions := NIL
   ::ReportOptions := NIL
   ::DllExecuteCall(::_CloseSyst)    // <- evtl. schauen, welche Wirkung eine Auskommentierung hat.
   ::frSystHandle := 0
RETURN self
Hinweis: Der Klassen-Code ist in der Datei FastRep.prg hinterlegt und muss zur Anwendung dazu gelinkt werden.

Gruß, Olaf

Re: Thread und Frax

Verfasst: Do, 05. Dez 2013 21:07
von brandelh
eine DLL zu entladen ist keine gute Idee !

Wenn ich das bei der QuickPDF gemacht habe wurde kein Speicher freigegeben und beim nächsten Objekt wird neuer Speicher belegt.
Das Ergebnis ist ein Programm das Speicher frisst, bis es beendet wird.

Also einfach die DLL nicht entladen, das wird automatisch vom OS erledigt sobald die EXE beendet wird.

Der "internal Error" tritt bei mir auch auf, wenn ich mit einem ungültigen handle auf eine DLL zugreifen will.
Wenn der Xbase++ code beiliegt kann man da ja nachbessern.

Bei der LibXL habe ich z.B. eine interne Variable mitgeführt, die verhindert, dass mehr als einmal der interne Speicher freigegeben wird (beim zweiten Aufruf => interne Datenstrukturen beschädigt ...
Auf Pablos Rat hin habe ich auch die numerische iVar (::nDLL) gegen den DLL-Namen ausgetauscht, dieser ist immer gültig :!:

also statt ::nDLL einfach 'LibXL' angeben.

Wie gesagt, wenn Ihr den Quellcode der Xbase++ Klasse habt, könnt Ihr die Mängel ausgleichen.

Re: Thread und Frax

Verfasst: So, 15. Dez 2013 9:24
von andreas
Hallo Werner,

ich hatte FRAX mit einem Dienst benutzt, der nur mit Threads gearbeitet hat. Einer der Threads hat zur bestimmten Zeit die Reports als PDF gespeichert und per Email versendet. Ich hatte nice PRobleme damit, dass Frax in Thread benutzt wurde.
Allerdings war das der einzige Thread, der Frax benutzt hat.

Re: Thread und Frax

Verfasst: So, 15. Dez 2013 21:41
von Werner_Bayern
Servus Andreas,

Du hast also auch nie die Konstellation, dass ein Thread ein oFrax:destroy() aufruft, während ein zweiter Frax-Thread läuft?

Wieso schreibst Du in der Vergangenheit, setzt Du Frax nicht mehr ein?

Re: Thread und Frax

Verfasst: Mi, 18. Dez 2013 16:25
von andreas
Hallo Werner,

die erwähnte Anwendung ist bei meinem alten Arbeitgeber geblieben.

Re: Thread und Frax

Verfasst: Mi, 18. Dez 2013 17:37
von Werner_Bayern
Servus Andreas,

danke für die Info. Du arbeitest also weiterhin mit Frax? Hat jemand schon die Kompatibilität mit Xbase++ 2.0 getestet?