Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Note that delegates don't keep the publisher alive (they only keep the target=subscriber alive), so no number of subscriptions will (by themselves) keep the broadcaster alive. As such, from this perspective it doesn't matter whether it is disposed or not. When there are no items referencing the broadcaster (and the event-subscriptions don't matter for this), it will be eligible for collection.</p> <p><em>Essentially</em>, a delegate is a (list of) pair(s) of <code>MethodInfo</code> and <code>object</code> references; the method to call, and the object to invoke as "arg0" (aka <code>this</code>). It simply doesn't have a reference to the object <em>raising</em> the event.</p> <p>Here's evidence that a listener <strong>does not</strong> keep the source alive; you should see that "Source 1" gets collected, even though we still have the matching listener that is subscribed. As expected, "Listener 2" does <em>not</em> get collected, since we still have the matching broadcaster:</p> <pre><code>class DataSource { public DataSource(string name) { this.name = name; } private readonly string name; ~DataSource() { Console.WriteLine("Collected: " + name); } public event EventHandler SomeEvent; } class DataListener { public DataListener(string name) { this.name = name; } private readonly string name; ~DataListener() { Console.WriteLine("Collected: " + name); } public void Subscribe(DataSource source) { source.SomeEvent += SomeMethodOnThisObject; } private void SomeMethodOnThisObject(object sender, EventArgs args) { } } static class Program { static void Main() { DataSource source1 = new DataSource("Source 1"), source2 = new DataSource("Source 2"); DataListener listener1 = new DataListener("Listener 1"), listener2 = new DataListener("Listener 2"); listener1.Subscribe(source1); listener2.Subscribe(source2); // now we'll release one source and one listener, and force a collect source1 = null; listener2 = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); // source 1 gets collected, ONLY Console.WriteLine("Done"); Console.ReadLine(); GC.KeepAlive(source2); // prevents collection due to optimisation GC.KeepAlive(listener1); // prevents collection due to optimisation } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload