Typen, die über systemeigene Ressourcen verfügen, sollten freigegeben werden können

Aktualisiert: November 2007

     TypeName

TypesThatOwnNativeResourcesShouldBeDisposable

CheckId

CA1049

Kategorie

Microsoft.Design

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Ein Typ verweist auf ein System.IntPtr-Feld, ein System.UIntPtr-Feld oder ein System.Runtime.InteropServices.HandleRef-Feld, implementiert jedoch nicht System.IDisposable.

Regelbeschreibung

Diese Regel setzt voraus, dass in den Feldern IntPtr, UIntPtr und HandleRef Zeiger auf nicht verwaltete Ressourcen gespeichert werden. Typen, die nicht verwaltete Ressourcen zuordnen, müssen IDisposable implementieren, damit Aufrufer diese Ressourcen bei Bedarf freigeben und die Lebensdauer der Objekte verkürzen können, die diese Ressourcen enthalten.

Aufgabe des empfohlenen Entwurfsmusters zum Bereinigen nicht verwalteter Ressourcen ist, sowohl ein implizites als auch ein explizites Mittel zum Freigeben dieser Ressourcen bereitzustellen. Dazu dient die Object.Finalize-Methode bzw. die IDisposable.Dispose-Methode. Der Garbage Collector ruft die Finalize-Methode eines Objekts zu einem nicht genau festgelegten Zeitpunkt auf, nachdem festgestellt wurde, dass das Objekt nicht mehr erreichbar ist. Nach dem Aufruf von Finalize wird zur Freigabe des Objekts eine zusätzliche Garbage Collection benötigt. Die Dispose-Methode ermöglicht dem Aufrufer, Ressourcen bei Bedarf explizit freizugeben. Die Ressourcen werden dabei früher freigegeben als unter dem Garbage Collector. Nach dem Bereinigen der nicht verwalteten Ressourcen muss Dispose die GC.SuppressFinalize-Methode aufrufen, um dem Garbage Collector mitzuteilen, dass Finalize nicht mehr aufgerufen werden muss. Damit entfällt die zusätzliche Garbage Collection, und die Lebensdauer des Objekts wird verkürzt.

Behandlung von Verstößen

Um einen Verstoß gegen diese Regel zu korrigieren, implementieren Sie IDisposable.

Wann sollten Warnungen unterdrückt werden?

Eine Warnung dieser Regel kann gefahrlos unterdrückt werden, wenn der Typ nicht auf eine nicht verwaltete Ressource verweist. Andernfalls sollten Sie keine Warnung dieser Regel unterdrücken, denn wenn IDisposable nicht implementiert wird, kann dies dazu führen, dass nicht verwaltete Ressourcen nicht verfügbar sind oder nicht verwendet werden.

Beispiel

Im folgenden Beispiel wird ein Typ gezeigt, der IDisposable implementiert, um eine nicht verwaltete Ressource zu bereinigen.

Imports System

Namespace DesignLibrary

    Public Class UnmanagedResources
        Implements IDisposable

       Dim unmanagedResource As IntPtr
       Dim disposed As Boolean = False

       Sub New 
           ' Allocate the unmanaged resource ...
       End Sub

       Overloads Sub Dispose() Implements IDisposable.Dispose
           Dispose(True)
           GC.SuppressFinalize(Me)
       End Sub

       Protected Overloads Overridable Sub Dispose(disposing As Boolean)
           If Not(disposed) Then

               If(disposing) Then
                   ' Release managed resources.
               End If

               ' Free the unmanaged resource ...

               unmanagedResource = IntPtr.Zero

               disposed = True

           End If
       End Sub

       Protected Overrides Sub Finalize()
           Dispose(False)
       End Sub

    End Class

End Namespace
using System;

namespace DesignLibrary
{
    public class UnmanagedResources : IDisposable
    {
        IntPtr unmanagedResource;
        bool disposed = false;

        public UnmanagedResources() 
        {
            // Allocate the unmanaged resource ...
        }

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    // Release managed resources.
                }

                // Free the unmanaged resource ...

                unmanagedResource = IntPtr.Zero;

                disposed = true;
            }
        }

        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
}

Verwandte Regeln

GC.KeepAlive beim Verwenden systemeigener Ressourcen aufrufen

Ordnungsgemäßes Aufrufen von GC.SuppressFinalize

Verwerfbare Typen sollten einen Finalizer deklarieren

Typen, die löschbare Felder besitzen, müssen gelöscht werden können

Siehe auch

Referenz

Implementieren der Methoden "Finalize" und "Dispose" zum Bereinigen von nicht verwalteten Ressourcen

Weitere Ressourcen

Bereinigen von nicht verwalteten Ressourcen