Pulizia delle risorse non gestite

Le attività di gestione della memoria vengono effettuate da Garbage Collector .NET per la maggior parte degli oggetti creati dall'app. Se però si creano oggetti che includono risorse non gestite, sarà necessario rilasciare esplicitamente queste ultime quando si smette di utilizzarle. Il tipo più comune di risorse non gestite è rappresentato dagli oggetti che eseguono il wrapping di risorse del sistema operativo, quali file, finestre, connessioni di rete o connessioni alle banche dati. Benché il Garbage Collector sia in grado di tenere traccia della durata di un oggetto in cui è incapsulata una risorsa non gestita, non dispone di dati sufficienti per effettuare il rilascio e la pulizia della risorsa non gestita.

Se i tipi utilizzano risorse non gestite, è necessario effettuare le operazioni seguenti:

  • Implementare lo schema Dispose. A tale scopo è necessario fornire un'implementazione IDisposable.Dispose per abilitare il rilascio deterministico delle risorse non gestite. Un consumer del tipo in uso chiama Dispose quando l'oggetto e le risorse che utilizza non sono più necessari. Il metodo Dispose rilascia immediatamente le risorse non gestite.

  • Nel caso in cui un consumer del tipo in uso ometta di chiamare Dispose, fornire un modo per rilasciare le risorse non gestite. A questo scopo è possibile procedere in due modi:

    • Utilizzare un handle sicuro per eseguire il wrapping della risorsa non gestita. Questa è la tecnica consigliata. Gli handle sicuri derivano dalla classe astratta System.Runtime.InteropServices.SafeHandle e includono un metodo Finalize affidabile. L'utilizzo di un handle sicuro richiede semplicemente l'implementazione dell'interfaccia IDisposable e la chiamata del metodo Dispose dell'handle sicuro nell'implementazione IDisposable.Dispose. Il finalizzatore dell'handle sicuro viene chiamato automaticamente dal Garbage Collector se non viene chiamato il metodo Dispose.

      Oppure:

    • Definire un finalizzatore. La finalizzazione abilita il rilascio non deterministico delle risorse non gestite quando il consumer di un tipo non riesce a chiamare IDisposable.Dispose per l'eliminazione deterministica.

      Avviso

      La finalizzazione dell'oggetto può essere un'operazione complessa e soggetta a errori, è consigliabile utilizzare un handle sicuro anziché fornire il proprio finalizzatore.

I consumer del tipo in uso possono quindi chiamare l'implementazione IDisposable.Dispose direttamente per liberare la memoria utilizzata dalle risorse non gestite. Quando si implementa correttamente un metodo Dispose, il metodo Finalize o il proprio override del metodo Object.Finalize diventa una misura di protezione per la pulizia delle risorse nel caso in cui il metodo Dispose non venga chiamato.

In questa sezione

Implementazione di un metodo Dispose: descrive come implementare il criterio Dispose per il rilascio delle risorse non gestite.

Uso di oggetti che implementano IDisposable: descrive come i consumer di un determinato tipo garantiscono che venga chiamata l'implementazione Dispose corrispondente. A tale scopo, si consiglia vivamente l'utilizzo di C# using o l'istruzione Using (in Visual Basic).

Riferimento

Tipo/Membro Descrizione
System.IDisposable Viene definito il metodo Dispose per il rilascio delle risorse non gestite.
Object.Finalize Provvede alla finalizzazione dell'oggetto se le risorse non gestite non vengono rilasciate dal metodo Dispose.
GC.SuppressFinalize Elimina la finalizzazione. Questo metodo viene abitualmente chiamato da un metodo Dispose per impedire l'esecuzione di un finalizzatore.