Manici vs.AddHandler
-
09-06-2019 - |
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?
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.