Non penso che lo schema faccia quello che ti aspetti. Stai cercando di impedire all'evento di mantenere un riferimento all'oggetto corrente in modo da prevenire perdite di memoria? L'espressione lambda acquisirà il valore di this
per valutare ProcessEvent
(supponendo che lo ProcessEvent
sia un metodo di istanza), quindi si verificherà ancora la perdita. Questo codice è lo stesso di SomeEvent += (sender, e) => ProcessEvent();
.
Si può tentare fare qualcosa di più come questo (che non è anche quello che si vuole):
var reference = new WeakReference((Action)ProcessEvent);
SomeEvent += (sender, e) => ((Action)reference.Target)();
Ora l'espressione lambda catturerà l'WeakReference, così non avrete un riferimento forte a this
. Sfortunatamente, nient'altro fa riferimento al delegato creato da ProcessEvent, quindi verrà rimosso sul prossimo GC anche se this
è ancora attivo. (Questo inoltre non controlla se Target è nullo).
Si potrebbe provare qualcosa di simile:
public EventHandler MakeWeakHandler(Action action, Action<EventHandler> remove)
{
var reference = new WeakReference(action.Target);
var method = action.Method;
EventHandler handler = null;
handler = delegate(object sender, EventArgs e)
{
var target = reference.Target;
if (target != null)
{
method.Invoke(target, null);
}
else
{
remove(handler);
}
};
return handler;
}
e quindi utilizzarlo in questo modo:
SomeEvent += MakeWeakHandler(ProcessEvent, h => SomeEvent -= h);
che manterrà debole di riferimento al ricevitore di processEvent, e rimuoverà automaticamente l'evento gestore dall'evento dopo che è stato raccolto, il che dovrebbe impedire perdite di memoria finché l'evento viene generato regolarmente.
Hai visto la mia domanda/risposta [qui] (http://stackoverflow.com/questions/1747235/weak-event-handler-model-for-use-with-lambdas)? Non è un one-liner, ma io * penso * funzioni ... – Benjol