Tenga en cuenta que los delegados no se mantienen con vida el editor (que sólo mantienen el target = suscriptor vivos), así que no hay número de suscripciones (por sí mismos) mantener la emisora vivo. Como tal, desde esta perspectiva, no importa si está dispuesto o no. Cuando no hay elementos que hagan referencia a la emisora (y las suscripciones a eventos no importan), será elegible para la recopilación.
Esencialmente, un delegado es un (lista de) par (s) de MethodInfo
y object
referencias; el método para llamar y el objeto para invocar como "arg0" (también conocido como this
). Simplemente no tiene una referencia al objeto elevando el evento.
Aquí hay evidencia de que un oyente no mantiene viva la fuente; debería ver que se obtiene la "Fuente 1", a pesar de que todavía tenemos el oyente coincidente que está suscrito. Como era de esperar, "Listener 2" hace no consiguen recogidos, ya que todavía tenemos la emisora juego:
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
}
}
Supongo que quiere decir "¿se retendrá el Oyente en la memoria?" –
Yo no. Me refiero a Broadcaster. La pregunta es sobre una fuente de evento que se eliminará mientras el suscriptor aún esté vivo. –
(respondió al nuevo comentario) –