Frage zu Dispose()

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 32 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Frage zu Dispose()

    Ist mir gerade aufgefallen, weil ich per Zufall einen Breakpoint gesetzt habe:
    Ich habe stellenweise das

    VB.NET-Quellcode

    1. Protected Overrides Sub Dispose(ByVal disposing As Boolean)

    aus dem .Designer in meine .vb verlegt um dort noch z.B. in .Load() eingerichtete Handler wieder zu entfernen.
    Jetzt ist es so, dass der Breakpoint in Dispose() seltsamer Weise erreicht wird, obwohl das zugehörige Form noch gar nicht geöffnet ist.
    Vielmehr passiert das, wenn ich mit der Maus im MenuStrip einen Menüpunkt ausklappe und dann mit der Maus nur darüber fahre, also nichts klicke.
    Bisher war ich der Ansicht, Dispose() wird nur ausgeführt, wenn ich ein Form schließe.
    Liege ich da falsch? Weil das Form ist mit Sicherheit noch NICHT geöffnet.
    Ich dachte erst, dass beim vorherigen Beenden der Application Dispose() evtl. nicht ausgeführt wurde und nun nach dem Neustart noch "nachgereicht" wird.
    Aber Dispose() wird beim Beenden sehr wohl ausgeführt. Aber halt auch bevor das Form überhaupt geöffnet wurde.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roepke“ ()

    Bitte detaillierte Infos geben oder Beispielprojekt hochladen.
    Wenn ich den Dispose-Teil von Form2 in die Form2.vb ziehe und das Form mit

    VB.NET-Quellcode

    1. Using f As New Form2
    2. f.ShowDialog(Me)
    3. End Using
    aufrufe, wird die Dispose-Methode erst bei Schließen von f aufgerufen - was so gewollt ist. Daher mach ich irgendwas anders als Du. Ich bitte um Klärung.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Das ist ein rießen Projekt und in besagtem Form läuft auch ein 2ter Thread.
    Der wird zwar augenscheinlich beim Schließen des Forms terminiert, aber ich will nicht ausschließen, dass da noch ganz massiv was schief läuft.
    Mir ging es in erster Linie mal darum sicher zu stellen, dass ich mit meinem Halbwissen was Dispose() angeht nicht ganz so falsch liege.
    Dispose() wenn ein Form geschlossen wird und nicht, wenn es noch gar nicht geöffnet ist.
    Wird es trotzdem aufgerufen, dann hat das wohl seine Gründe, die ich jetzt finden muss.

    roepke schrieb:

    Dispose() wenn ein Form geschlossen wird und nicht, wenn es noch gar nicht geöffnet ist.
    korrekt
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    roepke schrieb:

    Das ist ein rießen Projekt und in besagtem Form läuft auch ein 2ter Thread.
    Probier doch einfach, in einem kleinen zweiten (2., nicht aber 2ten) Testprojekt Deinen Effekt zu reproduzieren, Diesen Code lädtst Du dann hoch.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja gut, ein

    VB.NET-Quellcode

    1. Using f As New Form1
    2. End Using
    würde auch das Dispose auslösen. Das Folgende hingegen interessanterweise nicht:

    VB.NET-Quellcode

    1. Private Sub Foo()
    2. Dim f As New Form1
    3. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Das Folgende hingegen interessanterweise nicht:
    Doch, nach dem Schließen von Form1:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Bluespide schrieb:

    Designervorschau
    Funktioniert (auch) ohne geöffneten Designer.
    Ich denke nicht, dass der Designer auf Breakpoints reagiert (ungetestet).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Doch, nach dem Schließen von Form1
    Das ist klar, aber eben nicht beim Verlassen der Methode, obwohl da ja eigentlich normalerweise lokale Objekte über den Michael Jordan geschickt werden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Die werden dann tatsächlich vom Garbage Collector collected. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo, mal eine kurze Rückmeldung von mir.
    Ich kreise das Problem ein.
    Kehre ich zu einer älteren Version des Forms zurück, in dem (bisher) ohne erkennbaren Grund .Dispose() augerufen wird, dann wird es auch nicht mehr aufgerufen.
    Das Problem liegt also wohl im Form selbst.
    Ich werde mich jetzt Schrittweise durchhangeln und schauen ab welcher Stelle das Problem auftritt.
    Kann ja durchaus auch mit dem .Designer zusammenhängen.

    Haudruferzappeltnoch schrieb:

    Form1 muss dafür auch nicht geschlossen werden.
    Kannst Du das vorführen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    OK, ich habe eine Spur und auch eine Vermutung.
    Anbei mal ein absolut abgespecktes Projekt.
    Im 'frm_One.Designer.vb' Dispose() einen Breakpoint setzen.
    Programm starten.
    Im Menü ein DropDown öffen z.B. Tools (spielt aber scheinbar keine Rolle welches) und mit der Maus über die Einträge fahren, nichts anklicken.
    Nach einer kurzen Zeit wird der Breakpoint erreicht.
    Meine Vermutung ist, dass es etwas mit der Dim WithEvents frm_One_evts As New frm_One und dem anschließenden frm_One_evts = Nothing in frm_Main.vb zu tun hat.
    Generell bin ich nicht so glücklich damit.
    Ich benötige aber eine Möglichkeit, um auf Events des frm_One in frm_Main zu reagieren, wenn dieses geöffnet ist.
    Schöner wäre die Instanz erst zu erstellen, wenn sie wirklich geöffnet wird.
    Vermutlich wäre es sauberer das frm_One zu öffnen und dann die Events mittels AddHandler hinzuzufügen.
    Dateien
    Dein Menü und Dropdown lädt Dinge in den Speicher und lässt diese dann auch wieder fallen, das sind ja meist kurzfristige Anzeigen.
    Es liegt nahe, dass der GC da auch mal zwischenläuft, dann sind wir wieder bei Post 7 & 8. Sprich: Ist die Instanz von frm_one_evts noch in Benutzung in dem Moment wo du über dein Menü gehst?
    Naja frm_One_evts = Nothing sagt nein.

    Was ist dann mit Dim WithEvents frm_One_evts as frm_One? (Ohne New)
    Das ist im Endeffekt dasselbe wie New + Nothing, nur sinnvoller. Die kurz eingekloppte Instanz wird da collected

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Ich habe ja (zumindest als Benutzer) noch gar keine frm_One geöffnet, solange ich mit der Maus nur über das Menü fahre.
    Also aus Benutzersicht: nein, es ist keine Instanz von frm_One in Benutzung.
    Aber (und da komme ich auf Post 18 zurück) im Hintergrund kann das vermutlich sehr wohl der Fall sein, das ja in frm_Main eine Instanz angelegt und dann erst mal Nothing wird.