Zoeken…


Opmerkingen

Prestatiekritieke applicaties in beheerde .NET-applicaties kunnen ernstig worden beïnvloed door de GC. Wanneer de GC wordt uitgevoerd, worden alle andere threads opgeschort totdat deze zijn voltooid. Om deze reden wordt het aanbevolen om de GC-processen zorgvuldig te evalueren en te bepalen hoe deze kunnen worden geminimaliseerd.

Onbeheerde bronnen

Als we het hebben over de GC en de "heap", hebben we het echt over wat de managed heap wordt genoemd . Objecten op de beheerde heap hebben toegang tot bronnen die zich niet op de beheerde heap bevinden, bijvoorbeeld bij het schrijven naar of lezen uit een bestand. Onverwacht gedrag kan optreden wanneer een bestand wordt geopend om te worden gelezen en vervolgens een uitzondering optreedt waardoor de bestandsingang niet zoals normaal wordt gesloten. Om deze reden vereist .NET dat onbeheerde bronnen de IDisposable interface IDisposable . Deze interface heeft een enkele methode genaamd Dispose zonder parameters:

public interface IDisposable
{
    Dispose();
} 

Wanneer u onbeheerde bronnen hanteert, moet u ervoor zorgen dat deze correct worden verwijderd. U kunt dit doen door expliciet te bellen Dispose() in een finally blok, of met using verklaring.

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

of

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

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

De laatste is de voorkeursmethode en wordt tijdens compilatie automatisch naar de eerste uitgebreid.

Gebruik SafeHandle bij het inpakken van onbeheerde bronnen

Wanneer u wrappers schrijft voor onbeheerde bronnen, moet u SafeHandle in een subklasse SafeHandle plaats van zelf IDisposable en een finalizer te implementeren. Uw SafeHandle subklasse moet zo klein en eenvoudig mogelijk zijn om de kans op een lek in de handgreep te minimaliseren. Dit betekent waarschijnlijk dat uw SafeHandle-implementatie een intern implementatiedetail van een klasse zou zijn die deze omwikkelt met een bruikbare API. Deze klasse zorgt ervoor dat, zelfs als een programma uw SafeHandle instantie lekt, uw onbeheerde handle wordt vrijgegeven.

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;
    }
}

Disclaimer: dit voorbeeld is een poging om te laten zien hoe u een beheerde bron SafeHandle met SafeHandle die IDisposable voor u implementeert en de finalisten op de juiste manier configureert. Het is heel gekunsteld en waarschijnlijk zinloos om op deze manier een stuk geheugen toe te wijzen.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow