Je pensais que ce serait un modèle intéressant. Une collection d'objets est stockée dans une classe de gestionnaire. Lorsqu'un objet n'est pas nécessaire, il est supprimé de la collection. Si cela est nécessaire et que le GC ne l'a pas encore éliminé, interrogez l'instance de l'objet existant avec un événement faible. Par exemple:C# Re-Root Référence à l'objet Utilisation d'événements avant que le GC ne se déconnecte, motif de dépendance automatique Ergo et mémoire/mémoire CPU-efficace
class Manager
{
//--- Events ---
public event SearchingForInstanceEventHandler SearchingForInstance;
//--- Fields ---
List<OneOfMany> _many = new List<OneOfMany>();
//--- Constructors ---
public Manager()
{
// Create several OneOfMany instances.
_many.Add(new OneOfMany(this, "C:\file1.txt"));
_many.Add(new OneOfMany(this, "C:\file2.txt"));
_many.Add(new OneOfMany(this, "C:\file3.txt"));
// Erase the strong references to one or more OneOfMany instances.
_many.Clear();
// Attempt to find and reuse a previously generated instance, if the GC hasn't reclaimed it.
SearchingForInstanceEventArgs e = new SearchingForInstanceEventArgs("C:\file2.txt");
OnSearchingForInstance(e);
OneOfMany oneOfMany = e.OneOfMany;
// If a previously generated instance does not exist or has already been reclaimed by the GC, create a new one.
if (oneOfMany == null)
oneOfMany = new OneOfMany(this, "C:\file2.txt");
// Store a reference to it while it is needed.
_many.Add(e.OneOfMany);
}
//--- Protected Methods ---
protected virtual void OnSearchingForInstance(SearchingForInstanceEventArgs e)
{
if (SearchingForInstance != null)
SearchingForInstance(this, e);
}
}
class OneOfMany
{
//--- Fields ---
string _key;
Manager _manager;
//--- Constructors ---
public OneOfMany(Manager manager, string key)
{
_manager = manager;
_key = key;
_manager.SearchingForInstance += new SearchingForInstanceEventHandler(_manager_SearchingForInstance);
// INSERT HERE: Long process generating much data (worth reusing if still exists in memory, and worth freeing if not needed)
}
//--- _manager Event Handlers ---
void _manager_SearchingForInstance(object sender, SearchingForInstanceEventArgs e)
{
// If this is the instance the manager is searching for, return a reference to this.
if (e.Key == _key)
e.OneOfMany = this;
}
}
class SearchingForInstanceEventArgs : EventArgs
{
//--- Public Constructors ---
public SearchingForInstanceEventArgs(string key)
{
Key = key;
}
//--- Public Properties ---
public string Key { get; private set; }
public OneOfMany OneOfMany{ get; set; }
}
delegate void SearchingForInstanceEventHandler(object sender, SearchingForInstanceEventArgs e);
Cela peut être utilisé pour tirer profit de la mémoire du GC n'a pas disposé encore, et il peut utiliser le GC pour gérer automatiquement les dépendances pour vous. Par exemple, si la classe OneOfMany référence d'autres instances de OneOfMany (et en dépend), vous pouvez ajouter de nouvelles références (ie dépendances) en demandant une instance existante de celle dont vous avez besoin (avec un événement), et le GC supprimera automatiquement les instances ne dépendaient plus. Cela contraste avec le stockage de toutes les instances de OneOfMany dans une collection et l'interrogation de la collection pour une instance existante de la dépendance nécessaire, et le fait de devoir parcourir une arborescence de dépendances pour supprimer manuellement les dépendances non-rootées.
Cependant, mon souci avec ceci est ce que si une instance est re-rooted dans le GC pendant que le GC court? Est-il possible de faire une référence GC OneOfMany entre le moment où GC condamne OneOfMany et le moment où il le dispose? Si non, le GC peut-il être synchronisé avec ce modèle?
EDIT: Si la méthode actuelle de souscription à l'événement n'est pas faible, remplacez-la par une méthode faible.