I have a simple event defined using PRISM event aggregator pattern
public class TestEvent : PubSubEvent
{
}
public static class PrismEvents
{
public static readonly IEventAggregator EventAggregator = new EventAggregator();
public static readonly TestEvent EventTest = EventAggregator.GetEvent<TestEvent>();
}
I have a subscriber class where this event is subscribed using a lambda.Note the usage of a local variable(i) inside the subscription code
public class SubScriber
{
public SubScriber()
{
int i = 5;
PrismEvents.EventTest.Subscribe(() =>
{
Console.WriteLine("Event Fired");//not getting called
i = 10; //commenting this line will execute the subscription code
});
}
}
In the publisher side Subscriber is created, then GC is called then event publised.
Subscription code is not getting executed!
class Program
{
static void Main(string[] args)
{
new SubScriber();
GC.Collect(); //commenting this line will execute the subscription code
PrismEvents.EventTest.Publish();
Console.ReadKey();
}
}
Couple of points
Commenting the usage of local variable(i=10) will fix the issue.Subscription code will execute as expected
Commenting GC.collect will fix the issue. Subscription code will execute as expected
What is the reason for this behavior?
SubScriber
instance is entirely irrelevant, but a non-capturing lambda expression can be reused, hence, linked to the code creating it, which will use the same object each time you’re executing it, which will prevent its garbage collection. In contrast, a lambda expression capturing the currenti
variable has to produce a new instance each time the code is executed. Hence, the code will not keep a reference to it and it can be collected immediately after. – Holger