CA1049: Typen, die systemeigene Ressourcen besitzen, müssen gelöscht werden können
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.
Behandeln 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
CA2115: GC.KeepAlive beim Verwenden systemeigener Ressourcen aufrufen
CA1816: GC.SuppressFinalize korrekt aufrufen
CA2216: Verwerfbare Typen sollten einen Finalizer deklarieren
CA1001: Typen, die löschbare Felder besitzen, müssen gelöscht werden können
Siehe auch
Referenz
Implementing Finalize and Dispose to Clean Up Unmanaged Resources