Announcement

Collapse
No announcement yet.

Dynaische Controls erzeugen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dynaische Controls erzeugen

    Hallo zusammen,
    ich erzeuge z.B. ein Label:


    Code:
    If IsNothing(MyLabel) Then
      MyLabel = New Label
    '...
    End If
    In bestimmten Voraussetzungen benötige ich diese nicht mehr:

    Code:
    If Not IsNothing(MyLabel) Then
      MyLabel .Dispose()
      GC.Collect()
    End If
    Nun kann es vorkommen, das ich das Control doch noch mal benötige. Wenn ich dann wieder mit


    Code:
    If IsNothing(MyLabel) Then
      MyLabel = New Label
    '...
    End If
    das Control erzeugen möchte bekomme ich beim debuggen folgende Meldung:
    Auf verworfene Objekte kann nicht zugegriffen werden.

    Wie muss ich also das Control zerstören, bzw. wie muss ich den Wiederaufruf generieren, damit das funktioniert...???

    Danke

  • #2
    Hallo,

    um ein Objekt zu zerstören reicht es in .net dieses Objekt auf Nothing (in VB.net) bzw. auf null (in C#) zu setzen. Der Garba Collection erledigt die Arbeit selbstständig und muss nur in seltensten Fällen manuell zum Collect gezwungen werden.

    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Wenn du im Code auf IsNothing(MyLabel) prüfst und das als Indikator verwendest das dein Control auch disposed wurde dann mußt du nach dem disposen das entsprechende Control auch auf nothing setzen.


      If Not IsNothing(MyLabel) Then
      MyLabel .Dispose()
      GC.Collect()
      MyLabel = Nothing
      End If
      Wobei ich Gü recht gebe das disposen sollte eigentlich überflüssig sein.
      MyLabel nur auf nothing setzen reicht aber nicht, weil es vermutlich noch in der Controls Collection des ContainerControls steckt und damit referenziert bleibt, deshalb nicht finalisiert wird und damit weiterhin auf deiner Form zu sehen ist.

      Du mußt es also noch aus der Controls Collection des Parents entfernen.
      Wie das geht kann ich die leider nicht für VB zeigen bin C# fixiert.
      Vielleicht springt da grad mal jemand anderes ein und hilft aus. Gü?

      Comment


      • #4
        Controls Collection des ContainerControls steckt
        stimmt - hab ich unterschlagen (oder nur vergessen )

        Wie das geht kann ich die leider nicht für VB zeigen bin C# fixiert.
        Vielleicht springt da grad mal jemand anderes ein und hilft aus. Gü?
        Ich bin auch C# fixiert, aber mit http://www.developerfusion.com/tools.../csharp-to-vb/ schaff ich das - von früher her kenne ich VB6 und somit kann ich kurz prüfen ob passt.

        Als Beispiel:
        [highlight=vbnet]
        Imports System
        Imports System.Windows.Forms

        Namespace WindowsFormsApplication1
        Public Partial Class Form1
        Inherits Form
        Private _myLabel As Label

        Public Sub New()
        InitializeComponent()
        End Sub

        Private Sub button1_Click(sender As Object, e As EventArgs)
        If _myLabel Is Nothing Then
        ' Label erstellen:
        _myLabel = New Label()
        _myLabel.Text = DateTime.Now.ToLongTimeString()

        ' Label zur Form hinzufügen:
        Me.Controls.Add(_myLabel)
        Else
        ' Label aud der Form entfernen:
        Me.Controls.Remove(_myLabel)

        ' Label-Objekt "zerstören":
        _myLabel = Nothing
        End If
        End Sub
        End Class
        End Namespace
        [/highlight]

        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment


        • #5
          Danke Gü

          Comment


          • #6
            Erst mal Danke für Eure Antworten.
            Ich habe da noch nen bischen rumgetestet und was funktionierendes gefunden:

            Erstellen:

            Code:
            If MyLabel Is Nothing OrElse MyLabel.IsDisposed Then
               'wichtig IsDisposed, sonst wird das Label nach dem Disposen nicht mehr erstellt....
               MyLabel = New Label
               '.....
            End If
            Zerstören:

            Code:
            If Not IsNothing(MyLabel) Then
               MyLabel.Dispose()
            End If
            GC.Collect()
            Ich habe einige Male erlebt, dass trotz MyLabel.Dispose() ( wenn mehrere Controls zu entfernen waren ) das Control noch auf der Form zu sehen war. Aus diesem Grund habe ich zum Schluß die Carbage Collection mit GC.Collect() erzwungen.

            Comment


            • #7
              Aber mit meinem Code gehts auch ohne Dispose.

              mfG Gü
              "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

              Comment


              • #8
                Originally posted by gfoidl View Post
                Aber mit meinem Code gehts auch ohne Dispose.
                Wie meinst du das..? Ich muss doch irgendwo das Control zerstören...

                Comment


                • #9
                  Ja, das stimmt und wurde im bisherigen Verlauf auch schon behandelt.

                  Code:
                  _myLabel = Nothing
                  PS: Du musst lesen

                  mfG Gü
                  "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                  Comment


                  • #10
                    Du meinst ich sollte anstelle von

                    Code:
                    If Not IsNothing(MyLabel) Then
                       MyLabel.Dispose()
                    End If
                    GC.Collect()
                    folgendes verwenden ?

                    Code:
                    If Not IsNothing(MyLabel) Then
                       MyLabel = nothing
                    End If
                    Was hat das für einen Vorteil ?

                    Comment


                    • #11
                      Eines der Grundprinzipe von .net ist dass sich die CLR um die Garbage-Collection (GC) kümmert und nicht der Benutzer.

                      D.h. der Benutzer soll wenn er ein Objekt nicht mehr braucht dies nicht selbst zerstören sondern auf NULL bzw. NOTHING setzen um es so für den GC als zerstört zu markieren.

                      ZB kann ein Destruktor zwar implementiert werden, dieser lässt sich aber per Code nicht aufrufen - nur vom GC.

                      Der Hintergrund dieses vorgehens ist eine Erleichterung für den Programmierer um Speicherlecks zu verhindern. ZB wurden/werden in C++ Programmen manchmal der Aufruf von Destruktoren vergessen. Dies verhindert die CLR.

                      Wird ein Objekt auf NULL gesetz ist der Verweis weg und das Objekt existiert für die Anwendung nicht mehr - im Speicher liegt es noch so lange rum bis der GC es tatsächlich aus dem Speicher löscht.

                      Es ist schneller ein Objekt auf NULL zu setzen als es zu DISPOSEn.

                      Speicherprobleme gibt es heutzutage kaum mehr - daher ist es egal ob dieses Objekt im Speicher liegt bis der GC es entfernt.

                      Es gibt ein Programmiermuster von Microsoft das die von mir vorgeschlagene Vorgehensweise propagiert.

                      Hab ich dich jetzt ganz verwirrt?

                      mfG Gü
                      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                      Comment


                      • #12
                        OK. Erst mal Danke für deine Ausführungen....

                        Originally posted by gfoidl View Post
                        Hab ich dich jetzt ganz verwirrt?
                        Da muss ich erts mal drüber nachdenken...

                        Comment

                        Working...
                        X