Using und globale Variable

  • VB.NET

Es gibt 40 Antworten in diesem Thema. Der letzte Beitrag () ist von Storch.

    Using und globale Variable

    Hallo Leutz,

    Ich habe

    VB.NET-Quellcode

    1. Dim pComm As New frm_piccomments(StartPublishPicList)
    2. If frm_piccomments.m_ShowForm Then pComm.ShowDialog(Me)
    3. pComm.Dispose
    4. pComm = Nothing
    5. End Using

    ersetzt durch:

    VB.NET-Quellcode

    1. Using pComm As New frm_piccomments(StartPublishPicList)
    2. If frm_piccomments.m_ShowForm Then pComm.ShowDialog(Me)
    3. End Using


    Wie verhält es sich, wenn die Variable 'pComm' Klassenweit definiert wäre, also:

    VB.NET-Quellcode

    1. Private pComm as frm_piccomments
    2. Private Sub Irgendwas()
    3. Using pComm As New frm_piccomments(StartPublishPicList)
    4. If frm_piccomments.m_ShowForm Then pComm.ShowDialog(Me)
    5. End Using
    6. End sub

    Konkret, was passiert mit der Variable nach 'End Using'. Wird die sofort auf Nothing gesetzt oder behält sie ihren Inhalt bis sie erneut verwendet wird oder verliert sie ihren Inhalt erst, wenn der GarbageCollector zuschlägt?

    Ich frage das zum einen aus reiner Neugier, zum anderen ist es doch denkbar, das man eine solche Variable später auf ihren Inhalt bzw. Zustand , zB Nothing, prüfen will.
    Müsste da ein pComm = Nothing trotzdem gesetzt werden?

    Oder denke ich womöglich völlig falsch? Wäre für Erleuchtung wie immer sehr dankbar.
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!

    Storch schrieb:

    VB.NET-Quellcode

    1. frm_piccomments.m_ShowForm


    Was soll das bewirken? Du greifst nicht auf das Objekt, sondern auf die Klasse zu.

    Zu der eigentlichen Frage, probiere es doch aus. Setz Haltepunkt auf Using und steppe es durch, am Ende siehst du, ob das Objekt Nothing ist oder nicht. Wobei ich nicht verstehe, was Using an dieser Stelle dann überhaupt bewirken soll...
    m_ShowForm ist eine Booleansche Variable in frm_piccomments und dort als 'Public Shared' definiert. deswegen kann ich diese als Bedingung einsetzen, ob das Form auch tatsächlich angezeigt werden soll.

    Davon abgesehen, meine Frage galt dem Using. Da soll laut OH sicherstellen, dass Systemressourcen nach Ende des Usingblocks vom GarbageCollector aufgeräumt werden. So wie ich es verstanden habe, kann man sich dann das Dispose sparen.
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    Hi
    die GarbageCollection gibt im Optimalfall nur dann Objekte frei, wenn keine (nicht-schwachen) Referenzen mehr auf ein Objekt existieren. Wenn eben kein solcher (verwalteter) Verweis mehr existiert, kann nicht mehr direkt auf das Objekt zugegriffen werden und ist daher überflüssig. Die Freigabe erfolgt allerdings verzögert. Dispose gibt hingegen die Resource direkt frei und verhindert ggf. auch den Aufruf des "Finalizers" (das Objekt selbst wird trotzdem gelöscht). Die Freigabe erfolgt manuell.
    Das korrekte IDisposable.Dispose-Muster wird ja bereits gezeigt, sobald IDisposable implementiert wird. Der Aufruf von GC.SuppressFinalize führt eben dazu, dass die überschreibbare Finalisierungsmethode (oder auch Destruktor) eben ausgelassen wird.
    Ich glaube nicht, dass beim Using die Variable auf Nothing zurückgesetzt wird, ich glaube, dass nur die Resourcen freigegeben werden. Wenn kein Verweis mehr existiert, springt die GC sowieso im Anschluss an und markiert die Resource als nicht-verwiesen.

    Es kommt allerdings immer darauf an, wie genau IDisposable.Dispose umgesetzt wurde! Using ruft halt nur nach Abschluss der Aktion (wohl egal, wie) diese Methode auf.

    Gruß
    ~blaze~
    Mir ist gerade eingefallen, dass in deinem 2. Beispiel eine neue pComm innerhalb deiner Sub angelegt wird, auch wenn sie den gleichen Namen hat. Denn bei Using wird eine neue Variable angelegt, und wenn man in einer Methode eine Variable anlegen will, die gleich heißt, wie eine klassenweit gütige, es eine neue angelegt wird und innerhalb der Methode nur auf sie zugegriffen wird.
    @Sonne

    Warum, wie und wieso ich dort auf die m_FormShow zugreife möchte ich hier nicht diskutieren. Es hat nichts mit der Using-Angelegenheit zu tun und würde diesen Thread nur unnötig verlängern.

    Mein zweites Code-Beispiel ist in der Tat falsch formuliert. Ich habe Deinen Rat befolgt und mich mal durchgesteppt, mit folgendem (korrigierten) Code

    VB.NET-Quellcode

    1. Private pComm as frm_piccomments
    2. Private Sub Irgendwas()
    3. Using pComm = New frm_piccomments(StartPublishPicList)
    4. If frm_piccomments.m_ShowForm Then pComm.ShowDialog(Me)
    5. End Using
    6. End sub

    Im nächsten Schritt nach End Using ist die Variable = Nothing. Also scheint es zu funktionieren.

    @~blaze~
    Danke für die Hinweise.

    @all
    Ich rufe mehrere Formulare in dieser Manier auf:

    VB.NET-Quellcode

    1. Dim frmX As New frm_X
    2. frmX.ShowDialog(Me)
    3. frmX .Dispose()
    4. frmX = Nothing


    Wenn ich diese Aufruf über Using realisiere... muss sich da mit irgendwelchen Huddeleien rechnen oder ist das ein adäquate Möglichkeit?
    GUD Uwe

    :whistling: Wenn ich genau wüsste, was ich nicht weiß, dann wäre mein Wissen vollständig!
    @Storch:

    Du hast 2 Variablen. Eine globale und eine lokale. Deine beiden Variablen pComm haben nichts miteinander zu tun. Die Globale ist nur deswegen Nothing, da sie nicht instanziert ist. Using kannst Du nur innerhalb eines Methodenrumpfes verwenden. Mehr gibt es dazu nicht zu sagen.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    SpaceyX schrieb:

    Deine beiden Variablen pComm haben nichts miteinander zu tun

    Dem muss ich widerstrechen (siehe Anhang).
    Nach dem Using ist die Private Variable auch wieder Nothing. Inder Zeit innerhalb des Using Blocks hat diese sehr wohl ein Objekt.

    lg
    Bilder
    • form_1.png

      5,2 kB, 201×158, 465 mal angesehen
    • form2.png

      6,83 kB, 320×173, 108 mal angesehen
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Jetzt nochmal zum mitschreiben.

    Die globale Variable hast Du so deklariert:

    VB.NET-Quellcode

    1. Private p As Form2


    schon klar, dass das Nothing ist.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    sonne75 schrieb:

    dass es 2 Variablen mit demselben Namen angelegt werden
    Und wo wären die dann deklariert?
    @fichz: Ich pflichte Dir bei.
    @SpaceyX: Wie deklariert?
    Auch wenn es so deklatiert wird, ist es eine Instanz:

    VB.NET-Quellcode

    1. Private p As Form2
    2. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    3. Using p As New Form2
    4. p.ShowDialog()
    5. End Using
    6. End Sub
    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!
    Wie kann es dan sein, dass wenn die eine Variable per New ein Objekt erzeugt, die andere auch den Zeiger drauf hat obwohl diese vorher Nothing war?
    MMn. ist das die gleiche Variable. Man müsste es auch so schreiben können und es hätte den selben Effekt:

    VB.NET-Quellcode

    1. Private p As Form2
    2. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    3. p = New Form2
    4. p.ShowDialog()
    5. p.Dispose
    6. End Sub


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Na dann probier mal das:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private f2 As New Form2 With {.Text = "global"}
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. Using f2 As New Form2 With {.Text = "lokal"}
    5. f2.ShowDialog()
    6. End Using
    7. Me.f2.ShowDialog()
    8. End Sub
    9. End Class
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    sonne75 schrieb:

    Und wie kommst du drauf?

    Siehe meinen Post mit den 2 Screenshots. Da ist genau dieser Fall.

    SpaceyX schrieb:

    Na dann probier mal das:

    Das ist ein anderes Code als der vom TE. Hier wird eine Instanz gleich beim Deklarieren erstellt.
    Mein Post war auf den des TE bezogen und nicht auf diesen.

    Und bei dem vom TE ist es mMn die gleiche Variable, da die Private sonst nicht wüsste auf welches Objekt sie zeigen müsste.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten

    fichz schrieb:

    Siehe meinen Post mit den 2 Screenshots. Da ist genau dieser Fall.

    Eben nicht, du siehst nur "p" und weißt nicht, welche gerade gemeint wird. Hast du meinen Link gelesen? Da ist es doch sehr eindeutig beschrieben.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „sonne75“ ()