Verweise auf ein Objekt

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Verweise auf ein Objekt

    Hallo!

    Folgendes Beispiel:

    VB.NET-Quellcode

    1. dim obj as new object
    2. dim obj2 as object = obj


    Dieses Beispiel erstellt ein neues Objekt und weist dieses dann obj2 zu.
    Das Objekt existiert einmal im Speicher, wobei obj und obj2 darauf verweisen.
    Gibt es eine Möglichkeit abzufragen, wieviele Vereise auf ein Objekt existieren?

    vanitas-mundi schrieb:

    dann würde ich gerne das Objekt aus dem Dictionary werfen.

    Du könntest mit schwachen Verweisen arbeiten:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim o As Object
    3. Dim weakpointer As System.WeakReference
    4. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    5. o = Nothing
    6. End Sub
    7. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    8. ' assign
    9. o = New Object
    10. weakpointer = New WeakReference(o, False)
    11. End Sub
    12. Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
    13. If weakpointer.Target IsNot Nothing Then
    14. If MessageBox.Show("Wanna take the garbage out?") = Windows.Forms.DialogResult.OK Then
    15. GC.Collect()
    16. End If
    17. Else
    18. MessageBox.Show("He's dead Jim!")
    19. End If
    20. End Sub
    21. End Class

    Klick auf Button2, dann Button1, dann Button3, dann "OK" und oh' Wunder er ist weg ;)

    Wie gesagt: Das ganze funzt nur, NACHDEM der GC aufgeräumt hat. Solange ist das Objekt zwar nicht referenziert, könnte aber bei Bedarf jederzeit wieder zurückgeholt werden.
    Oder Du zählst selbst, wenn ein neuer Verweis generiert bzw. ein alter gelöscht 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!
    Erst einmal ein Danke für die Hilfe - besonders an picoflop!

    Ein weakpointer ist bestimmt eine tolle Sache - dummerweise hilft er mir nicht weiter.

    Ich habe eine Klassenbibliothek, welche mir auf Anfrage Objekte erzeugt, diese per Funktion
    zurück gibt und für einen Direktzugriff die Instanz mit einigen Nutzdaten, in ein Dictinary packt
    (ein ungefähres Beispiel):

    VB.NET-Quellcode

    1. public function CreateObject as object
    2. dim obj = new object
    3. _dic.add(obj,"Meine Daten")
    4. return obj
    5. end function



    So, jetzt habe ich in der Klassenbibliothek die Möglichkeit, bei Übergabe der Instanz,
    die Nutzdaten aus dem dic zu ermitteln.

    Wenn jetzt aber im Hauptprogramm das erzeugte Objekt stirbt, wird es eigentlich nicht mehr
    benutzt, aber mein Dictinary wächst stetig weiter, weil ich dies nicht mit bekomme.

    Hat für dieses Problem jemand eine Lösung?

    vanitas-mundi schrieb:

    Wenn jetzt aber im Hauptprogramm das erzeugte Objekt stirbt, wird es eigentlich nicht mehr
    benutzt, aber mein Dictinary wächst stetig weiter, weil ich dies nicht mit bekomme.

    Hat für dieses Problem jemand eine Lösung?

    Versteh nicht, wo das Problem ist.

    VB.NET-Quellcode

    1. Dim obj As New Object
    2. _dic.Add(New WeakReference(obj), "foo")
    3. ' Ist mindestens EIN Objekt im Dictionary schon tot?
    4. If (From w In _dic.Keys Where Not w.IsAlive Select 1 Take 1).Count > 0 Then
    5. ' Entferne alle Referenzen, die nicht mehr verwendet werden
    6. End If

    Das macht dann doch, was du willst?
    Hallo!

    Nunja, in etwa ...

    Ich benutze das Dictionary, um einen schnellen Direktzugriff zu haben.

    Wenn ich nun den Weakpointer zum key mache, ist der Geschwindigkeitsvorteil weg,
    wenn ich an meine Nutzdaten möchte, könnte ich es z.B. per LINQ lösen:

    VB.NET-Quellcode

    1. 'Momentan
    2. public function Get Nutzdaten(byval obj as object) as string
    3. return _dic.item(obj)
    4. end sub
    5. 'Per Weakpointer
    6. public function Get Nutzdaten(byval obj as object) as string
    7. dim ret = from key in _dic where key.target is obj select _dic.item(key)
    8. return _dic.item(0)
    9. end sub


    Habe jetzt einfach ohne Editor das Beispiel geschrieben. Jetzt befürchte ich, dass die WeakPointer-Lösung,
    bei einer größeren Menge gespeicherter Objekte etwas träge wird.


    EDIT:

    habe es jetzt einmal mit 5000000 Objekten getestet, die LINQ-Abfrage ist quasi sofort ausgeführt
    (hätte ich nicht gedacht), werde also deinen Lösungsansatz einmal weiter testen.

    DANKE!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „vanitas-mundi“ ()

    Ich hatte WeakReference eiglich noch anners verstanden.
    Damit kann man ZusatzDaten wie zusätzliche Properties an beliebige Objekte dranpatchen. Räumt der GC die Objekte auf, dann auch die ZusatzDaten.

    Insofern würde sich ein Dictionary erübrigen, denn man muß nicht mehr mit dem Objekt als Key einen Wert suchen, sondern der Wert ist ja direkt drangepatcht (äh - im Hintergrund einer Weakreference werkelt glaub ein Dictionary, aber eins, was dick Freund ist mit Kollege GC)

    ErfinderDesRades schrieb:

    Damit kann man ZusatzDaten wie zusätzliche Properties an beliebige Objekte dranpatchen.

    Nein.
    Dazu kann man sie AUCH verwenden ;)
    Der eigentliche Zweck ist aber halt nur, einen Verweis zu haben, der den GC nicht am "aufräumen" hindert. Kann man zb relativ einfach einen Cache mit aufbauen. Und das ist im Prinzip ja wohl genau das, was VM will:
    msdn.microsoft.com/de-de/library/system.weakreference.aspx
    naja - ich verstehe auch noch nicht klar, worums hier geht:
    Ob Vanitas Mundi Nutzdaten an Objekte dranpatchen will,
    oder ob er einen Cache braucht, um ein u.U. teures Erstellen von Objekten zu vermeiden, wenn ein Objekt mit gleichen Daten bereits vorher schonmal erstellt wurde.