2009-02-09 15 views
5

So che quando si registra un oggetto sugli eventi collegati al mouse, si verificano perdite di memoria. Ecco perché è necessario utilizzare WeakEvent pattern.In che modo i controlli WPF integrati gestiscono i gestori di eventi su un evento collegato?

Ho un problema con questo modello: se si desidera utilizzarlo, non è possibile definire il gestore nel codice XAML.

Per me, significa che ogni codice come questo perdite:

<SomeControl Mouse.MouseDown="MyHandler" /> 

A meno che non si rimuove il gestore esplicitamente nel codice (e dubito che qualcuno lo fa). Ora c'è qualcosa che non capisco:

<Button Click="MyHandler" /> 

Questo codice in qualche modo utilizzare qualche caso Mouse.MouseDown per rilevare un clic sul pulsante. Con alcune ricerche con reflector, ho scoperto che questo evento utilizza MouseDown della classe UIElement. E quando leggo il codice di UIElement non capisco: non c'è WeakEventManager!

Qualcuno può spiegarmi come UIElement riceve gli eventi da Mouse.MouseDown senza perdite?

risposta

7

L'utilizzo di normali gestori in XAML non richiede riferimenti deboli.

Quello che stai facendo è creare un riferimento di memoria tra il controllo principale e un controllo figlio contenuto in questo controllo; il controllo figlio in questo caso è il pulsante.

Se qualcuno mantiene un riferimento a qualsiasi parte dell'albero visivo per il controllo principale, l'intero albero rimarrà in memoria perché è collegato insieme (riferimenti padre/figlio).

Ora se tutti i riferimenti a questo albero vengono rimossi, il riferimento di evento tra padre e figlio (il controllo principale e il pulsante) non è significativo perché questi controlli erano già collegati tramite riferimenti padre/figlio. Una volta rimossi tutte le referenze esterne, questo controllo può essere sottoposto a garbage collection.

I gestori di eventi all'interno di XAML creano solo riferimenti di eventi interni.

È necessario fare attenzione quando i client esterni si registrano a un evento su un controllo, perché si sta creando un riferimento esterno che manterrà il controllo attivo finché il collegamento e il client esiste (a meno che non sia un riferimento debole) .

La tua domanda riguarda eventi collegati. Non sembra esserci alcuna documentazione chiara sul fatto che gli eventi collegati causino perdite di memoria. A me sembra che il controllo dell'interfaccia utente che sottoscrive l'evento contenga riferimenti all'evento anziché viceversa, ma presumo che l'oggetto evento statico debba avere un modo per notificare al controllo che è stato attivato. Sembra che ci sia una sorprendente mancanza di commenti su questo da Microsoft.

+0

Sono d'accordo con te, tuttavia il gestore di XAML su un evento collegato (non parlo degli eventi di controlli ma degli eventi come Mouse.MouseDown) può perdere, perché su di esso è sempre presente un riferimento. Internamente, la classe Button usa gli eventi Mouse.MouseDown (UIElement per essere specifici). E non so perché questo non perde. –

+0

Buon punto. Gli eventi associati sono riferimenti esterni. –

Problemi correlati