If I have a code that looks something like this:
public void Foo()
{
Bar bar = new Bar();
bar.SomeEvent += (sender, e) =>
{
//Do somethin
The above answers are correct; I just wanted to make a note. Anonymous delegates used as handlers can only be unsubscribed if you retain some other reference to the delegate/lambda. This is because lambdas are "function literals", kind of like string literals, however unlike strings they are NOT compared semantically when determining equality:
public event EventHandler MyEvent;
...
//adds a reference to this named method in the context of the current instance
MyEvent += Foo;
//Adds a reference to this anonymous function literal to MyEvent
MyEvent += (s,e) => Bar();
...
//The named method of the current instance will be the same reference
//as the named method.
MyEvent -= Foo;
//HOWEVER, even though this lambda is semantically equal to the anonymous handler,
//it is a different function literal and therefore a different reference,
//which will not match the anonymous handler.
MyEvent -= (s,e) => Bar();
var hasNoHandlers = MyEvent == null; //false
//To successfully unsubscribe a lambda, you have to keep a reference handy:
EventHandler myHandler = (s,e) => Bar();
MyEvent += myHandler;
...
//the variable holds the same reference we added to the event earlier,
//so THIS call will remove the handler.
MyEvent -= myHandler;
Well, the object bar
refers won't be automatically garbage collected immediately... it's just that the bar
variable won't prevent it from being garbage collected.
The event handler won't prevent the instance of Bar
from being garbage collected either though - the "normal" problem is that an event handler keeps the subscriber of an event from being garbage collected (if it uses an instance method or captures "this" in an anonymous function). It doesn't usually affect the publisher being garbage collected. Just remember that the publisher needs to keep a reference to all the subscribers - the subscriber doesn't need to remember what it's subscribed to, unless it explicitly wants to unsubscribe or use some other member later.
Assuming nothing else is keeping your instance of Bar
alive, your code should be fine.
Your situation is fine; the event subscriber will not prevent the publisher from being collected, but the opposite can happen.
For example,
class Foo
{
public event EventHandler FooEvent;
void LeakMemory()
{
Bar bar = new Bar();
bar.AttachEvent(this);
}
}
class Bar
{
void AttachEvent(Foo foo)
{
foo.FooEvent += (sender, e) => { };
}
}
In this case, the instance of Bar
created within LeakMemory
can't be collected until either
FooEvent
's invocation listThis is because the event (which is just some syntactic sugar over an ordinary delegate
instance) holds onto a list of delegates to invoke when it's invoked, and each of these delegates has, in turn, a reference to the object that it's attached to (in this case, the instance of Bar
).
Note that we're only talking about collection eligibility here. Just because it's eligible doesn't say anything about when (or even, really, if) it will be collected, just that it can be.