using innerhalb von try --> benötigt man trotzdem finally?

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von raist10.

    using innerhalb von try --> benötigt man trotzdem finally?

    Angenommen ich habe das Objekt „myOwnObject“ welches die IDisposable-Schnittstelle implementiert und angenommen es wird mit einem using-Block innerhalb eines try-Blocks verwendet und innerhalb des using-Blocks tritt eine Exception auf.
    Wird Dispose() des Objektes trotzdem aufgerufen, oder muss dafür dann noch extra ein finally-Block folgen?

    Reicht es so?

    VB.NET-Quellcode

    1. try
    2. using myOwnObject As New OwnObject()
    3. ' Do Something, witch causes an exception
    4. End Using
    5. Catch ex As Exception
    6. ' Catch the Exception
    7. End Try


    Oder benötige ich noch einen finally-Block?

    VB.NET-Quellcode

    1. try
    2. using myOwnObject As New OwnObject()
    3. ' Do Something, witch causes an exception
    4. End Using
    5. Catch ex As Exception
    6. ' Catch the Exception
    7. Finnaly
    8. myOwnObject.Dispose()
    9. End Try
    Nein, da im Normalfall(wenn mich jetzt nich alles täuscht) das Using am Ende sowieso ein Dispose macht.
    Desweiteren hast du notfalls immer noch die 'Garbage Control' welche solche Arbeiten meiner Meinung nach sehr gut erledigt.

    lg.
    lg.

    LucaWelker

    LucaWelker schrieb:

    Nein, da im Normalfall(wenn mich jetzt nich alles täuscht) das Using am Ende sowieso ein Dispose macht.

    GambaJo meint ja wenn eine Exception auftritt kommt er nicht zu der End Using Zeile sondern fällt in den Catch Block

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Einfach ausprobieren? Wenn man nicht auf die Disposed Eigenschaft deines Objekts zugreifen kann, einfach zum Testen ne eigene kleine Klasse mit IDisposeable machen in der mutwillig eine Exception ausgeworfen wird.

    Die Disposed-Variable machst du dann Public und rufst sie nach dem Try Block einfach mal ab.
    @fichz: Ah okey, sorry das hab ich wohl falsch verstanden. Allerdings bleibt immer noch der Garbage Collector, welcher das Zeug zwar nicht sofort wegräumt aber wenn nötig. Also ein Speicherleck wird es hier definitiv nicht geben.

    Ansonsten kann ich dodo nur zustimmen.

    @Dodo: Deine Signatur is geil, den gleichen Spruch hat ein Klassenkammerad gestern bei uns im IT Unterricht gebracht als wir eine ähnliche Schaltung gesehen haben xD

    lg.
    lg.

    LucaWelker
    Okay, meine erste Idee funktioniert nicht, da man auf die Variable nicht zugreifen kann wenn sie außerhalb des Using Blocks steht, also habe ich einfach in die Dispose-Methode eine MsgBox eingebaut und die Exception ausgeführt und bevor die MsgBox der Exception kommt wird das Objekt disposed.

    Hier zum Testen:

    VB.NET-Quellcode

    1. Public Class Test
    2. Implements IDisposable
    3. Private disposedValue As Boolean = False ' So ermitteln Sie überflüssige Aufrufe
    4. Public Sub EX()
    5. Throw New Exception("Test")
    6. End Sub
    7. ' IDisposable
    8. Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    9. If Not Me.disposedValue Then
    10. If disposing Then
    11. ' TODO: Anderen Zustand freigeben (verwaltete Objekte).
    12. End If
    13. MsgBox("Disposed")
    14. ' TODO: Eigenen Zustand freigeben (nicht verwaltete Objekte).
    15. ' TODO: Große Felder auf NULL festlegen.
    16. End If
    17. Me.disposedValue = True
    18. End Sub
    19. #Region " IDisposable Support "
    20. ' Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren.
    21. Public Sub Dispose() Implements IDisposable.Dispose
    22. ' Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(ByVal disposing As Boolean) Bereinigungscode ein.
    23. Dispose(True)
    24. GC.SuppressFinalize(Me)
    25. End Sub
    26. #End Region
    27. End Class


    Aufruf:

    VB.NET-Quellcode

    1. Try
    2. Using t As New Test
    3. t.EX()
    4. End Using
    5. Catch ex As Exception
    6. MsgBox(ex.Message)
    7. End Try
    @Dodo: Thx

    LucaWelker schrieb:

    @fichz: Ah okey, sorry das hab ich wohl falsch verstanden. Allerdings bleibt immer noch der Garbage Collector, welcher das Zeug zwar nicht sofort wegräumt aber wenn nötig. Also ein Speicherleck wird es hier definitiv nicht geben.


    Wenn in dem Objekt z.B. mehrere hundert oder tausend Dateien geöffnet werden möchte man nicht warten. Wenn man z.B. eine Datei im Zugriff hat, möchte man, dass sie nicht so lange gesperrt bleibt, bis der GC Lust hat das Objekt zu terminieren.

    VB.NET-Quellcode

    1. try
    2. using myOwnObject As New OwnObject()
    3. ' Do Something, witch causes an exception
    4. End Using
    5. Catch ex As Exception
    6. ' Catch the Exception
    7. Finnaly
    8. myOwnObject.Dispose()
    9. End Try
    kann schon deshalb nicht funktionieren, weil myOwnObject außerhalb der Using-Schleife nicht definiert ist.
    Im Falle einer Exception wird die Using-Schleife ordnungsgemäß beendet.
    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: narf, da hätte ich auch selbst drauf kommen können.

    Mir ist nur gerade wichtig, dass in einer solchen Situation die Ressourcen ordnungsgemäß entladen werden, sonst geht schnell gar nichts mehr hier.
    Ist jetzt zwar nicht ganz das vom Thema aber generell zu Using.
    Was macht dies genau bzw wo liegt der Unterschied beispielsweise bei einem OpenFileDialog

    VB.NET-Quellcode

    1. using ofd as new OpenFileDialog
    2. If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
    3. messagbow.show("Pfurz")
    4. end If
    5. end using
    6. '-------------------------
    7. dim ofd as new OpenFileDialog
    8. If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
    9. messagbow.show("Pfurz")
    10. end If


    Wird der Speicher da im unterem Beispiel nicht freigegeben?

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Irgendwann schon. Wenn der GC sich das Objekt vornimmt.

    Mit using bzw. Dispose() wird der Speicher auch nicht wirklich freigegeben. Dort werden nur die Ressourcen, die man in diesem Objekt genutzt hat, entladen (sofern man dies in Dispose() so implementiert hat). Ob der GC dabei auch „gezwungen“ wird dieses Objekt an sich zu entladen, bezweifle ich, da das ja gegen das Prinzip des „intelligenten“ und selbst agierenden GCs verstoßen würde. Aber sicher bin ich mir nicht.
    Also erzielt wie unten beschrieben beides den gleichen Effekt?

    VB.NET-Quellcode

    1. using ofd as new OpenFileDialog
    2. If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
    3. messagbow.show("Pfurz")
    4. end If
    5. end using
    6. '-------------------------
    7. dim ofd as new OpenFileDialog
    8. If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
    9. messagbow.show("Pfurz")
    10. end If
    11. ofd.Dispose()

    ?

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Das using hilft auch bei größeren Methoden, da das Dispose() eventuell schon irgendwo vorkommen kann, aber z.B. in irgendeinem If oder else zweig, wo das Programm unter umständen gar nicht hinkommt. Daher ist using die sicherere Variante, die aber nichts anderes macht, als Dispose() auszurufen.

    LucaWelker schrieb:

    Allerdings bleibt immer noch der Garbage Collector, welcher das Zeug zwar nicht sofort wegräumt aber wenn nötig. Also ein Speicherleck wird es hier definitiv nicht geben.


    Jein, es gibt auch durchaus Objekte die die GC selber überhaupt nicht aufräumt, wie z.B. COM-Objekte (unmanaged Ressourcen). Die MUSST Du tatsächlich selber per Anweisung entladen, bzw. per marshallen freigeben, ansonsten hast Du die bis zum Ultimo aktiv im Speicher. Und das kann u.U. sehr übel sein. ;)

    Gruß

    Rainer
    Klar schadet es nicht:) Sagt ja auch keiner:) ICh benutze auch meistens usings grade bei Streamwriter/reader geschichten. Das Dispose verwende ich eher selten, allerdgins hab ich es auch schon benutzt.

    lg.
    lg.

    LucaWelker