Disposen von Klassen ohne Instanz

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

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

    Haudruferzappeltnoch schrieb:

    Rufe ich einfach NurSharedClass.SharedDisposable.Dispose auf?
    Wenn eine Klasse IDisposable implementiert, musst Du davon mit New eine Instanz erstellen. Bei einer "ordentlichen Aufräumaktion" wird dann das, was zu disposen ist, zerstört.
    Im Gegensatz zu einem Shared-Konstruktor, der aufgerufen wird, wenn erstmals auf shared Mamber zugegriffen wird, gibt es da keinen äquivalenten Dispose-Mechanismus.
    Insofern ist es ein Fehl-Design, IDisposable Shared Member anzulegen.
    Diese sollten Nicht-Shared Member in einer instanziierbaren Klasse sein.
    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!
    Letztenendes müsste die Containerklasse eine CleanUp/Dispose/Aufräum-Methode haben, die die Shared-Disposable-Members disposed. Und dann müsstest Du immer daran denken, diese am Ende auch aufzurufen …
    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.
    In der Aufräum Methode rufe ich aber dann auch nur Dispose für die einzelnen Member auf. Was ist dann der Unterschied?
    Ich zeichne mal wieder, und ein Teil des Bildes ist immer gleich, das soll eine Achsenbeschriftung sein. Deswegen packe ich die ganze Zeichnung in eine Containerklasse damit ich nicht jedesmal die Werte ausrechne. Aber der Pen und der Brush muss wenn das Form Close ja disposed werden.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Friend Class Axisdisplay
    2. Friend Shared Property Axislbl As Font
    3. Friend Shared Property Displaysize As Size
    4. Friend Shared Property Displayratio As SizeF
    5. Friend Shared blackpen As Pen
    6. Friend Shared blackbrush As SolidBrush
    7. Friend Shared Sub DrawMe(g As Graphics)
    8. For h = 100 To 3800 Step 100
    9. If h Mod 500 = 0 Then
    10. Continue For
    11. End If
    12. Dim PosY = Displaysize.Height - h * Displayratio.Height
    13. g.DrawLine(blackpen, 50, PosY, 40, PosY)
    14. Next
    15. For w = 100 To 2200 Step 100
    16. If w Mod 500 = 0 Then
    17. Continue For
    18. End If
    19. Dim PosX = w * Displayratio.Width + 50
    20. g.DrawLine(blackpen, PosX, Displaysize.Height, PosX, Displaysize.Height + 10)
    21. Next
    22. blackpen.Width = 4
    23. For h = 500 To 3500 Step 500
    24. Dim PosY = Displaysize.Height - h * Displayratio.Height
    25. g.DrawLine(blackpen, 50, PosY, 35, PosY)
    26. g.DrawString(h.ToString, Axislbl, blackbrush, 0, Displaysize.Height - h * Displayratio.Height - 15)
    27. Next
    28. For w = 500 To 2000 Step 500
    29. Dim PosX = w * Displayratio.Width + 50
    30. g.DrawLine(blackpen, PosX, Displaysize.Height, PosX, Displaysize.Height + 15)
    31. g.DrawString(w.ToString, Axislbl, blackbrush, w * Displayratio.Width + 28, Displaysize.Height + 15)
    32. Next
    33. blackpen.Width = 2
    34. End Sub
    35. Friend Shared Sub DisposeMe
    36. blackpen.Dispose
    37. blackbrush.Dispose
    38. End Sub
    39. End Class

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

    Font ist auch disposable, diese bitte nicht vergessen!
    Aber letztenendes könntest Du auch die Klasse IDisposable implementieren lassen. Dann wär es das offizielle Pattern.
    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.
    @Haudruferzappeltnoch Alle diese Member / Properties sollten nicht Shared sein!
    Wenn Du zwei Instanzen davon anlegst, sind diese Member / Properties für beide identisch.
    Wenn nur eine Instanz vorkommt, wäre es egal, aber man tut es einfach nicht.
    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!
    Man könnte dies sicherstellen, indem man aus der Klasse ein Singleton macht. Aber was spricht eigentlich für die Shared-Member-Variante?
    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.

    Haudruferzappeltnoch schrieb:

    da braucht man ja nicht mehrere von.
    Doch.
    Dann, wenn Du UserControls baust, die Du mehrfach auf das GUI ziehst.
    So solltest Du stets denken.
    Shared nur dann, wenn dieser Wert / diese Prozedur unabhängig von Klasseninstanzen verwendet wird.
    Bei Prozeduren z.B. dann, wenn nicht auf Instanz-Member und -Prozeduren zugegriffen wird.
    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!
    Hast Du mal n Screenshot? Wie kannst Du ausschließen (auch für zukünftige Entwicklung der Programms), dass wirklich nie mehr als ein AxisDisplay im ganzen Programm/-ablauf gebraucht wird?
    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 hab ich mich auch schon gefragt, wenn die Anwendung schließt, müssen die Objekte nicht sowieso verschwinden? Aber ich denke dann wär das mitm Disposen nicht so relevant, wenns so einfach wäre.

    Da ist fast die ganze Form nur ein Bild. Habe auch überlegt das einfach als Image inner Picturebox als Hintergrund reinzutun. Aber gezeichnet wird da ja auch.
    Bilder
    • achsen.png

      4,84 kB, 779×700, 56 mal angesehen

    Haudruferzappeltnoch schrieb:

    müssen die Objekte nicht sowieso verschwinden?
    In diesem Falle räumt das System auf.
    Für Dich wird das relevant, wenn Du ein und dieselbe Klasse mehrfach instanziierst und beim Schließen nicht aufräumst.
    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!

    Haudruferzappeltnoch schrieb:

    denn ich finde das etwas widersprüchlich.
    Ja.
    Bei sorgfältiger Programmierung wird aufgeräumt.
    Ich bemühe mich, sorgfältig zu programmieren.
    Bei umfassender Beantwortung Deiner Frage kommt dann eben auch die andere Seite zum Tragen.
    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!

    Haudruferzappeltnoch schrieb:

    Das hab ich mich auch schon gefragt, wenn die Anwendung schließt, müssen die Objekte nicht sowieso verschwinden? Aber ich denke dann wär das mitm Disposen nicht so relevant, wenns so einfach wäre.
    Dochdoch - die verschwinden dann.
    Also Disposen von Shared Objekten (also einzigen) halte ich in den meisten Fällen nicht für so relevant - bislang bin ich damit nur mit unaufgeräumten FileStreams auf Nase gefallen.
    Aber Disposen von normalen - nicht einzigen - Objekten ist höchst relevant.

    Ein Einziges Objekt (Singleton, Shared Member) ist ja nur eines und wird niemals mehr - über die ganze Laufzeit der Anwendung hin.
    Normale Objekte können aber tausende werden - also wenn bei jedem Öffnen und Schliessen eines Dialogs da mw. 20 unaufgeräumte GraphicsPathes anfallen - nicht die reine Lehre.
    Das m.E. wesentliche der IDisposable Schnittstelle: Wenn Du sie implementierst, hast Du ne Dispose-Methode, die Du dann aufrufen kannst. Ok, und was bringt Dir das im Vergleich zu einer eigenen CleanUp-Methode, die Du genauso aufrufen könntest? Die Möglichkeit, einen Usingblock zu erstellen.

    VB.NET-Quellcode

    1. Using DeineKlasseninstanz As New DeineKlasseDieIDisposableImplementiert
    2. 'hier der Code, der mit Deiner Klasse arbeitet
    3. End Using 'hier wird !automatisch! die Dispose-Methode Deiner Klasse aufgerufen

    Das klappt mit Klassen, die die IDisposable Schnittstelle nicht implementieren, natürlich nicht.
    Gibt wohl noch tiefer im System einen Unterschied (Finalize aufrufen oder eben auch nicht), aber das kann bestimmt ein anderer erklären.
    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.

    Haudruferzappeltnoch schrieb:

    die IDisposable Schnittstelle verstehe ich einfach nicht.
    Zwei Sachen:
    Die erste hast Du eben bei VaporiZed gelesen.
    Das andere ist:
    Du kannst eine IDisposable implementierende Klasse in einem Using-Block anlegen, so wie jeden "normalen" Dialog.
    Da lässt ews sich seher schön mit arbeiten.
    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!
    Kapier isch net, was Du damit meinst …
    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.