2010-07-16 15 views
7

Ho bisogno di un modo per tenere traccia delle istanze di varie classi, senza che queste classi abbiano alcuna conoscenza di essere monitorate. Essenzialmente, ho una factory class che crea istanze e le consegna ad un altro thread. Una volta che il thread completa e scarica l'istanza, ho bisogno di essere informato di ciò in modo da poter fare il conteggio dei riferimenti e uscire dal mio factory di classe quando tutte le istanze sono sparite.Ricevi notifica di smaltimento/distruzione di oggetti

La sfida è che non posso modificare nessuna delle classi che caricherò, perché non controllo il loro codice sorgente.

Tenere traccia delle istanze che creo è semplice, posso semplicemente inserirle in una sorta di raccolta mentre le creo. Monitorare la loro distruzione mi sta causando problemi. Se potessi modificare il codice sorgente, aggiungerei un evento a ogni classe e quando creerò un'istanza, collegherei all'evento e usarlo come notifica. Ma non posso farlo.

Quindi, la domanda è questa: c'è un modo subdolo per monitorare un'istanza dell'oggetto e rilevare quando viene distrutta?

risposta

3

Non c'è un modo per ottenere una notifica attiva, ma è possibile mantenere uno WeakReference agli oggetti e controllare periodicamente se sono morti.

Modifica: Mi piace la risposta di Reed meglio della mia!

+0

+1 È divertente - stavo pensando la stessa identica cosa, fino a quando ho letto la parte in cui diceva che stava controllando la costruzione degli oggetti;) –

+0

Sembra davvero che sia la soluzione più praticabile nella mia situazione, I ' farò un tentativo. –

+0

Mi piace il tuo meglio di Reed perché significa che i clienti di quel tipo non hanno bisogno di sapere di un tipo di decoratore speciale –

0

ne dite di controllare la distruzione dell'oggetto:

public void Destroy(T obj) 
{ 
    if (obj == null) 
     throw new ArgumentNullException("obj"); 
    if (!_living.Contains(obj)) 
     throw new ArgumentException("Where did this obj come from?"); 

    using (obj as IDisposable) 
    { 

    } 

    _living.Remove(obj); // List? 
} 
+0

Così che chiama Destroy()? Ricorda che non riesco a controllare i tipi che sto caricando (in effetti sono caricati dinamicamente da una cartella e non so in anticipo cosa troverò lì). –

10

Dal momento che si sta creando gli oggetti, sembra che si potrebbe restituire un Decorator invece dell'istanza reale.

Utilizzando lo Decorator Pattern, è possibile "avvolgere" l'oggetto restituito nella propria API decorata. La decorazione potrebbe fornire un'implementazione idonea che ha fornito la notifica di distruzione.

+0

Questo è bello. Puoi usare refection per generare il decoratore. Questo sarebbe importante se la classe è massiccia. – ChaosPandion

+0

È molto interessante, lo seguirò. Grazie. –

2

Se si tiene un elenco dei riferimenti alle istanze che si creano non otterranno garbage collection e così non sarà mai distrutta ...

invece si può creare un repository che contiene un elenco di GUID e creare una nuova guida per ogni istanza e poi aggiungerla ad una lista - qualcosa come un FactoryRepository. In questo modo non hai un problema di riferimento per la garbage collection poiché i Guids sono strutture piuttosto che tipi di riferimento. Potresti quindi ereditare da ogni classe per creare un tipo che può notificare su destroy. Suppongo che, dato che non è possibile modificare il codice delle classi originali, non è possibile alterare i consumatori di queste classi, quindi qualcosa come il modello decoratore (tramite un'interfaccia) è fuori perché i tipi non sarebbero compatibili.

esempio molto semplificato:

public class OriginalClassDestroyNotifier : OriginalClass 
{ 
    private readonly Guid _instanceId; 

    public OriginalClassDestroyNotifier(Guid instanceId) 
    { 
     _instanceId = instanceId; 
    } 

    ~OriginalClassDestroyNotifier() 
    { 
     FactoryRepository.NotifyDestroyed(_instanceId); 
    } 
} 
Problemi correlati