![]() |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Zitat:
|
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Zitat:
Die erste Exception tritt leider nicht immer genau gleich an der selben Stelle auf, sondern immer bei irgendeiner Art von Finalization. Recht häufig war das z.B. die Finalization vom WPViewPDF, aber nicht nur, weswegen ich das eher als Folgefehler ansehen würde, genau wie vorher Styles, die ich momentan deaktiviert habe. Der einzige größere Zusammenhang ist, dass unten im Stack immer System.FinalizeUnits zu laufen scheint. |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Zitat:
|
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Wo steht der Aufruf des Anmeldeformulares, was steht zwischen diesem Aufruf und dem Application.Run?
Das von Dir beschriebene Szenario "Anmeldemaske mit Abbruchmöglichkeit" löse ich für gewöhnlich in der Art:
Delphi-Quellcode:
begin
Application.Initialize; // hier der Aufruf der Anmeldemaske: // Anmeldemaske erstellen oder passende Methode aufrufen ... if Anmeldemaske.ShowModal = mrOk then begin // Von den Initialisierungen der Formulare ... wird beim Abbruch nix benötigt. // also werden sie vor der Entscheidung, ob Anmeldung oder Abbruch, nicht erstellt. Application.CreateForm(TfmMain, fmMain); // ... und alle anderen Formulare ... Application.Run; end else begin // nix oder Meldung des Programmabbruches ... // Hier ist Application.Terminate eine schlechte Idee. // Wenn schon CreateForms vor der Entscheidung, dann wird hier das Hauptformular des Programmes geschlossen, // damit alle anderen auch die Chance bekommen, ordentlich aufzuräumen. // Application.MainForm.Close; // Wobei: Die Erfahrung zeigt, dass auch das nicht immer zwingend ohne negative Nebenwirkungen "durchläuft". // Z. B. Irgendwo in 'nem FormCreate oder einer DFM wird/ist ein Timer auf True gesetzt, Thread erstellt, ... end; end. |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Zitat:
Das scheint völlig zufällig zu sein. Ich wills nur sicherheitshalber nochmal zusammenfassen, einfach weil ich mit diesem Kram bisher noch nie herumschlagen musste und dementsprechend vielleicht etwas falsch verstehe: Ich starte das Programm im Debugger, schließe es direkt in der Anmeldung wieder und halte bei der Exception, die dann kommt, an. Daraufhin schaue ich mir den Aufrufstack des Hauptthreads an: Relativ konsistent ist, dass das Programm im System.FinalizeUnits steckt, doch die Details weiter oben im Stack wechseln. Ist halt immer irgendeine Finalization von verschiedenen Units, bei der dann etwas ziemlich mundänesknallt. Momentan z.B. ist es ein FinalizeRecord in XML.xmlutil.Finalization. Wenn ich das Programm das nächste mal starte und bei der Exception halte, ist es was ganz anderes. Das wirkt für mich so, als hätte ich allgemeineres Problem, was wechselnde Folgefehler verursacht oder interpretiere ich das Problem irgendwie falsch dahingehend, dass doch eine einzelne Unit der Schuldige sein müsste? Ich habe halt keine Ahnung, wie das FinalizeUnits bzw der gesamte Ablauf nach dem Terminate arbeitet. |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Zitat:
Vor Anzeige der Anmeldemaske werden diverse Sachen gemacht, dabei auch mit einigen wenigen ausgewählten Forms. Der grundsätzliche Aufbau ist ähnlich wie bei dir, d.h. Application.Run wird nur ausgeführt, wenn man durch die Anmeldung durchgeht; in meinen Fall hier wird es also nicht ausgeführt. Und nur nochmal kurz allgemein: Meine Projekt-DPR hat sich zur funktionierenden Vorversion quasi nicht verändert und schon gar nicht das grundsätzliche Startverhalten. Liege ich richtig damit, dass das Problem, was auch immer es sein mag, dementsprechend in Units/Formen liegen muss, die vor der Anmeldung bereits verwendet werden und von mir zur Vorversion hin verändert/hinzugefügt worden sind? |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Wenn da etwas im Speicher kaputt geht, wäre FastMM mit FullDebugMode einen Versuch wert...
Und dann kann das Problem ganz woanders liegen als die Änderung, die das Auftreten ausgelöst hat. Dennoch könntest du, da es ja reproduzierbar ist, in der Versionsverwaltung versuchen, die Änderungen der Reihe nach durchzugehen und zu schauen, ab wann das auftritt. |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Wo der Fehler auftritt ist abhängig davon, wie schnell auf Abbruch geklickt wird. Derweil von dem Zeitraum ist abhängig, wie weit der Verarbeitungsfortschritt ist und wann das Terminate dann dem Prozess und/oder den inzwischen gestarteten Threads, ... die Daseinsberechtigung unter dem Hintern wegzieht.
Application.Terminate ist da einfach eine schlechte Idee. Initialisierung zu Ende durchlaufen lassen und dann erst den Anmeldedialog anzeigen und dann beim Abbruch das Hauptformular des Programmes schließen, damit ein geordnetes Programmende möglich wird oder den Anmeldedialog zuerst anzeigen und nur dann die übrige Initialisierung laufen lassen, wenn kein Abbruch gewünscht ist. Andernfalls suchst Du die 'nen Wolf und wirst höchstwahrscheinlich keinen dauerhaften Erfolg haben. Sinspin schriebe nicht umsonst: Zitat:
Zitat:
Bevor Du "ewig und drei Tage" weitersuchst, versuche es bitte einmal in der Form:
Delphi-Quellcode:
begin
Application.Initialize; // Anmeldemaske erstellen und anzeigen with TLoginForm.Create(nil) do try if ShowModal = mrOk then begin // Initialisierungen der Formulare nur bei erfolgreicher Anmeldung Application.CreateForm(TfmMain, fmMain); // Weitere Formulare initialisieren ... Application.Run; end else begin // Bei Abbruch oder fehlgeschlagener Anmeldung wird das Programm beendet // Application.Terminate wird vermieden, um unerwünschte Nebenwirkungen zu verhindern end; finally Free; end; end. |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Grundsätzlich stimme ich zu, dass es sinnvoll ist, die Projektdatei gut zu strukturieren. Ich persönlich sorge auch dafür, dass initialization und finalization nach Möglichkeit keinen Code enthalten, der dann direkt ausgeführt wird. Sprich ich verwende ein eigenes Framework, das diese Schritte zentral im Rahmen von Aufrufen aus der Projektdatei erledigt. Dadurch sind diese beim "end." der Projektdatei bereits abgearbeitet.
Deshalb ist der Vorschlag, Application.Run ggf. gar nicht erst auszuführen, schon gut. Allerdings dürfte korrekter Code durch Application.Terminate nicht zu einem Fehler führen. |
AW: Die Anweisung in [...] verwies auf Arbeitsspeicher bei [...]
Per se kann Application.Terminate nicht zu einem Fehler führen, da es erstmal nur eine Message an Application sendet, wo dann eine Variable (Terminated) auf True gesetzt wird,
worauf z.b. auch Threads reagieren können, um beim Ende sich ordentlich zu beenden. Eigentlich würde ein Programm so lange laufen, bis ALLE Threads (der MainThread ist nur Einer von Vielen) beendet wurden. OK, die RTL (Delphi) sorgt bei ordnungsgemäßem Ende des MainTreads dafür, dass der "Prozess terminiert" wird, womit dann noch laufende Threads gekillt werden. ABER, es ist inzwischen möglich, auch ein paar OnTerminate-Events zu registrieren, um darüber das Beenden zu beenden (abzubrechen, also das ordnungsgemäße Beenden des Programms zu verbieten) ACHTUNG: So lange keine TerminateProcs registriert sind, ist Application.Terminate per se thread-save, mit aber nicht, da die TerminateProcs vor dem Senden der Message abgehandelt werden. :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz