Nota che i delegati non mantengono viva l'editore (tengono solo il target = abbonato vivo), in modo che nessun numero di abbonamenti saranno (da soli) mantenere vivo l'emittente. In quanto tale, da questa prospettiva non importa se è disposto o meno. Quando non ci sono articoli che fanno riferimento all'emittente (e le sottoscrizioni agli eventi non contano per questo), sarà idoneo per la raccolta.
Essenzialmente, un delegato è un (elenco) coppia (s) di MethodInfo
e object
riferimenti; il metodo da chiamare e l'oggetto da richiamare come "arg0" (alias this
). Semplicemente non ha un riferimento all'oggetto che aumenta l'evento.
Ecco le prove che un ascoltatore non mantiene la sorgente viva; dovresti vedere che "Sorgente 1" viene raccolta, anche se abbiamo ancora il listener corrispondente che è iscritto. Come previsto, "Listener 2" fa non ottenere raccolti, dal momento che abbiamo ancora l'emittente corrispondente:
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
}
}
fonte
2010-01-05 22:18:56
Immagino tu voglia dire "l'ascoltatore verrà conservato in memoria?" –
Io no. Mi riferisco a Broadcaster. La domanda riguarda una fonte di eventi che viene eliminata mentre un utente è ancora in vita. –
(risposto al nuovo commento) –