0
0
C Sharp (C#)programming~20 mins

Event unsubscription and memory in C Sharp (C#) - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Event Memory Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output of this event subscription code?

Consider the following C# code where an event is subscribed and then triggered. What will be printed to the console?

C Sharp (C#)
using System;

class Publisher {
    public event Action OnChange;
    public void Raise() {
        OnChange?.Invoke();
    }
}

class Subscriber {
    public void Subscribe(Publisher p) {
        p.OnChange += () => Console.WriteLine("Event triggered");
    }
}

class Program {
    static void Main() {
        Publisher pub = new Publisher();
        Subscriber sub = new Subscriber();
        sub.Subscribe(pub);
        pub.Raise();
    }
}
ARuntime exception
BEvent triggered
CNo output
DCompilation error
Attempts:
2 left
💡 Hint

Think about what happens when the event is raised after subscription.

Predict Output
intermediate
2:00remaining
What happens if you forget to unsubscribe from an event?

Given the code below, what will be the output after GC.Collect() is called?

C Sharp (C#)
using System;

class Publisher {
    public event Action OnChange;
    public void Raise() {
        OnChange?.Invoke();
    }
}

class Subscriber {
    public Subscriber(Publisher p) {
        p.OnChange += Handler;
    }
    void Handler() {
        Console.WriteLine("Handled event");
    }
    ~Subscriber() {
        Console.WriteLine("Subscriber finalized");
    }
}

class Program {
    static void Main() {
        Publisher pub = new Publisher();
        Subscriber sub = new Subscriber(pub);
        sub = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        pub.Raise();
    }
}
ANo output
B
Subscriber finalized
Handled event
C
Handled event
Subscriber finalized
DHandled event
Attempts:
2 left
💡 Hint

Think about whether the subscriber object is collected by the garbage collector.

🔧 Debug
advanced
3:00remaining
Why does this event unsubscription fail to prevent memory leaks?

Examine the code below. The developer tries to unsubscribe the event to avoid memory leaks but it doesn't work. Why?

C Sharp (C#)
using System;

class Publisher {
    public event Action OnChange;
    public void Raise() => OnChange?.Invoke();
}

class Subscriber {
    private Publisher _pub;
    public Subscriber(Publisher pub) {
        _pub = pub;
        _pub.OnChange += Handler;
    }
    public void Unsubscribe() {
        _pub.OnChange -= () => Console.WriteLine("Handled");
    }
    private void Handler() {
        Console.WriteLine("Handled");
    }
}

class Program {
    static void Main() {
        Publisher pub = new Publisher();
        Subscriber sub = new Subscriber(pub);
        sub.Unsubscribe();
        pub.Raise();
    }
}
AThe lambda used in Unsubscribe is a different delegate instance than the one subscribed, so unsubscription fails.
BThe event is null so unsubscription throws an exception.
CThe Handler method is private and cannot be unsubscribed.
DThe Publisher class does not support unsubscription.
Attempts:
2 left
💡 Hint

Consider how delegates and lambdas work in C# when subscribing and unsubscribing.

Predict Output
advanced
3:00remaining
What is the output when using weak event pattern?

Consider this code using a weak event pattern to avoid memory leaks. What will be printed?

C Sharp (C#)
using System;
using System.Runtime.CompilerServices;

class Publisher {
    public event Action OnChange;
    public void Raise() => OnChange?.Invoke();
}

class Subscriber {
    public Subscriber(Publisher pub) {
        WeakReference<Subscriber> weakRef = new WeakReference<Subscriber>(this);
        pub.OnChange += () => {
            if (weakRef.TryGetTarget(out var target)) {
                target.Handler();
            }
        };
    }
    public void Handler() {
        Console.WriteLine("Handled via weak ref");
    }
    ~Subscriber() {
        Console.WriteLine("Subscriber finalized");
    }
}

class Program {
    static void Main() {
        Publisher pub = new Publisher();
        Subscriber sub = new Subscriber(pub);
        sub = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        pub.Raise();
    }
}
AHandled via weak ref
B
Subscriber finalized
Handled via weak ref
C
Subscriber finalized
No output from event
DNo output
Attempts:
2 left
💡 Hint

Think about whether the subscriber is still alive when the event is raised.

🧠 Conceptual
expert
3:00remaining
Which statement best explains event unsubscription's role in memory management?

Choose the best explanation for why unsubscribing from events is important to prevent memory leaks in C#.

AEvent subscriptions create strong references from the publisher to the subscriber, preventing garbage collection unless unsubscribed.
BUnsubscribing events automatically frees all memory used by the subscriber immediately.
CEvents use weak references by default, so unsubscription is only needed for performance reasons.
DSubscribers hold references to publishers, so unsubscribing breaks this link to avoid leaks.
Attempts:
2 left
💡 Hint

Consider how event delegates hold references internally.