Ich glaube nicht, dass dieses Muster das tut, was Sie erwarten. Möchten Sie verhindern, dass das Ereignis einen Verweis auf das aktuelle Objekt enthält, um Speicherlecks zu vermeiden? Der Lambda-Ausdruck erfasst den Wert this
, um ProcessEvent
auszuwerten (vorausgesetzt, ProcessEvent
ist eine Instanzmethode), so dass Sie immer noch das Leck haben. Dieser Code ist der gleiche wie SomeEvent += (sender, e) => ProcessEvent();
.
Möglicherweise versuchen Sie, etwas mehr wie dies zu tun (was auch nicht das, was Sie wollen):
var reference = new WeakReference((Action)ProcessEvent);
SomeEvent += (sender, e) => ((Action)reference.Target)();
die WeakReference Jetzt fängt der Lambda-Ausdruck, so dass Sie nicht eine starke Referenz haben zu this
. Leider verweist nichts anderes auf den Delegat, der von ProcessEvent erstellt wurde, daher wird er auch beim nächsten GC entfernt, auch wenn this
noch aktiv ist. (Dies überprüft auch nicht, ob das Ziel null ist).
Man könnte so etwas wie dies versucht:
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;
}
und es dann wie folgt verwenden:
SomeEvent += MakeWeakHandler(ProcessEvent, h => SomeEvent -= h);
, dass ein schwachen Bezug auf den Empfänger von Process halten wird, und wird das Ereignis automatisch entfernen Handler des Ereignisses, nachdem es gesammelt wurde, was Speicherlecks verhindern sollte, solange das Ereignis regelmäßig ausgelöst wird.
Haben Sie meine Frage/Antwort [hier] (http://stackoverflow.com/questions/1747235/weak-event-handler-model-for-use-with-lambdas) gesehen? Es ist kein One-Liner, aber ich denke * es funktioniert ... – Benjol