Domanda

C'è un vantaggio dinamico di collegamento/scollegamento di gestori di eventi?

Sarebbe manualmente staccando gestori di contribuire a garantire che non c'è un riferimento rimanenti per un smaltiti oggetto?

È stato utile?

Soluzione

Non è una questione di AddHandler contro Maniglie.

Se siete preoccupati per il riferimento al gestore di eventi interferire con la raccolta dei rifiuti, si dovrebbe utilizzare RemoveHandler, a prescindere di come il gestore è stato attaccato.La forma o il controllo del metodo Dispose, rimuovere eventuali gestori.

Ho avuto situazioni in Windows Form applicazioni.NET 1.1 giorni) in cui un gestore di evento sarebbe stato chiamato controlli che non aveva altri riferimenti per loro (e per tutti gli effetti erano morti e avrei pensato state GC alizzato) - estremamente difficile eseguire il debug.

Vorrei utilizzare RemoveHandler per sbarazzarsi di gestori, sui controlli che non si sta per il riutilizzo.

Altri suggerimenti

Sono abbastanza sicuro che il Handles la clausola è solo " zucchero sintattico e inserisce un AddHandler istruzione nel costruttore.Ho provato a utilizzare questo codice e disabili il framework di applicazione in modo che il costruttore non avrebbe roba extra:


Public Class Form1

    Public Sub New()
        ' This call is required by the Windows Form Designer. '
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call. '
        AddHandler Me.Load, AddressOf Form1_Load
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim breakpoint As Integer = 4
    End Sub
End Class

Il finito come questo:

  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  call       instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.0
  IL_000a:  dup
  IL_000b:  ldvirtftn  instance void WindowsApplication1.Form1::Form1_Load(object,
                                                                           class [mscorlib]System.EventArgs)
  IL_0011:  newobj     instance void [mscorlib]System.EventHandler::.ctor(object,
                                                                          native int)
  IL_0016:  call       instance void [System.Windows.Forms]System.Windows.Forms.Form::add_Load(class [mscorlib]System.EventHandler)

 '... lots of lines here '

  IL_0047:  ldarg.0
  IL_0048:  callvirt   instance void WindowsApplication1.Form1::InitializeComponent()
  IL_004d:  nop
  IL_004e:  ldarg.0
  IL_004f:  ldarg.0
  IL_0050:  dup
  IL_0051:  ldvirtftn  instance void WindowsApplication1.Form1::Form1_Load(object,
                                                                           class [mscorlib]System.EventArgs)
  IL_0057:  newobj     instance void [mscorlib]System.EventHandler::.ctor(object,
                                                                          native int)
  IL_005c:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Form::add_Load(class [mscorlib]System.EventHandler)
  IL_0061:  nop
  IL_0062:  nop
  IL_0063:  ret
} // end of method Form1::.ctor

Notare due blocchi identici di codice IL_000b e IL_0051.Penso che sia solo " zucchero sintattico.

Dichiarare un campo come WithEvents causa il compilatore di generare automaticamente una proprietà con lo stesso nome.Il getter restituisce il valore di un campo di backup.Il setter è un po ' più complicato.Prima controlla se il campo di backup già ha il valore corretto.Se è così, si esce.In caso contrario, se il campo di backup non è null, "problemi " RemoveHandler" le richieste di tutti i suoi eventi all'oggetto identificato dal campo di backup.A quel punto, indipendentemente dal fatto che il campo di backup non era null, imposta pari al valore richiesto.Infine, se il nuovo valore non è nullo, se il vecchio era o non, le questioni di proprietà "AddHandler" le richieste di tutti i suoi eventi all'oggetto identificato dal nuovo valore.

A condizione che ci si mette tutti di un oggetto WithEvents membri Nothing prima di abbandonarla, ed evita la manipolazione WithEvents membri in più thread, l'auto-generato il codice di evento non possa perdere.

Trovo che dinamicamente il collegamento/scollegamento di gestori di eventi è solo nel caso in cui si dispone di un lungo vissuto oggetto espone gli eventi che sono utilizzati da molti di breve durata oggetti.Per la maggior parte degli altri casi, i due oggetti sono disposti intorno allo stesso tempo e il CLR fa un sufficiente lavoro di pulizia, di propria iniziativa,

Ho allegare manualmente i gestori quando ho creare manualmente i controlli (ad esempio, la creazione dinamica di una casella di testo per ogni record del database).Ho disconnettere manualmente gestori di quando stanno gestendo le cose non sono pronti a gestire ancora (forse perché sto usando sbagliato eventi?:) )

Manualmente scollegamento di un evento può essere importante per evitare perdite di memoria:l'oggetto che si connette a un evento generato da un altro oggetto, non sarà di immondizia raccolti fino a che l'oggetto che genera l'evento è di garbage collection.In altre parole, un "evento-raiser" ha un forte riferimento per tutti gli "eventi-ascoltatori", ad esso connesso.

La maggior parte del tempo, il quadro si prende cura di questo per voi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top