Ricerca…


Osservazioni

Le applicazioni critiche per le prestazioni nelle applicazioni .NET gestite possono essere gravemente influenzate dal GC. Quando viene eseguito il GC, tutti gli altri thread vengono sospesi fino al completamento. Per questo motivo, si consiglia di valutare attentamente i processi del GC e determinare come minimizzare quando viene eseguito.

Risorse non gestite

Quando parliamo di GC e di "heap", stiamo parlando di ciò che viene chiamato heap gestito . Gli oggetti nell'heap gestito possono accedere alle risorse non nell'heap gestito, ad esempio, durante la scrittura o la lettura da un file. Un comportamento imprevisto può verificarsi quando, un file viene aperto per la lettura e quindi si verifica un'eccezione, impedendo la chiusura dell'handle del file normalmente. Per questo motivo, .NET richiede che le risorse non gestite implementino l'interfaccia IDisposable . Questa interfaccia ha un unico metodo chiamato Dispose senza parametri:

public interface IDisposable
{
    Dispose();
} 

Quando si gestiscono risorse non gestite, è necessario assicurarsi che siano correttamente smaltite. È possibile farlo chiamando esplicitamente Dispose() in un blocco finally o con un'istruzione using .

StreamReader sr; 
string textFromFile;
string filename = "SomeFile.txt";
try 
{
    sr = new StreamReader(filename);
    textFromFile = sr.ReadToEnd();
}
finally
{
    if (sr != null) sr.Dispose();
}

o

string textFromFile;
string filename = "SomeFile.txt";

using (StreamReader sr = new Streamreader(filename))
{
    textFromFile = sr.ReadToEnd();
}

Quest'ultimo è il metodo preferito e viene automaticamente esteso al primo durante la compilazione.

Usa SafeHandle durante il wrapping delle risorse non gestite

Quando si scrivono wrapper per risorse non gestite, è necessario SafeHandle sottoclasse SafeHandle piuttosto che provare a implementare IDisposable e un finalizzatore. SafeHandle sottoclasse SafeHandle dovrebbe essere il più piccola e semplice possibile per ridurre al minimo la possibilità di una perdita di handle. Ciò probabilmente significa che l'implementazione di SafeHandle fornirebbe un dettaglio di implementazione interna di una classe che lo avvolge per fornire un'API utilizzabile. Questa classe garantisce che, anche se un programma perde l'istanza di SafeHandle , l'handle non gestito viene rilasciato.

using System.Runtime.InteropServices;

class MyHandle : SafeHandle
{
    public override bool IsInvalid => handle == IntPtr.Zero;
    public MyHandle() : base(IntPtr.Zero, true)
    { }

    public MyHandle(int length) : this()
    {
        SetHandle(Marshal.AllocHGlobal(length));
    }

    protected override bool ReleaseHandle()
    {
        Marshal.FreeHGlobal(handle);
        return true;
    }
}

Dichiarazione di non responsabilità: questo esempio è un tentativo di mostrare come proteggere una risorsa gestita con SafeHandle che implementa IDisposable per te e configura i finalizzatori in modo appropriato. È molto inventato e probabilmente inutile allocare un blocco di memoria in questo modo.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow