CA1049: Typy, které vlastní nativní prostředky by měly být uvolnitelné
TypeName |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
Kategorie |
Microsoft.Design |
Narušující změna |
Nenarušující |
Příčina
Typ odkazuje na pole IntPtr a na pole UIntPtr nebo na pole HandleRef, ale neimplementuje IDisposable.
Popis pravidla
Toto pravidlo předpokládá, že pole IntPtr, UIntPtr a HandleRef obsahují ukazatele na nespravované zdroje.Typy, které přidělují nespravované prostředky, by měly implementovat IDisposable a umožnit tak volajícím uvolnit tyto prostředky na požádání a zkrátit životní cyklus objektů, které je využívají.
Doporučený návrhový vzor pro vyčištění nespravovaných zdrojů je poskytnutí implicitních a explicitních prostředků pro jejich uvolnění použitím metody Object.Finalize a metody IDisposable.Dispose.Uvolňování paměti volá metodu Finalize objektu v nestanovené době po tom, co je objekt označen jako již déle nepřístupný.Po zavolání Finalize, další je pro uvolnění objektu zapotřebí další uvolnění paměti.Metoda Dispose umožňuje volajícímu explicitně uvolnit zdroje na požádání dříve, než by byly přenechány uvolňování paměti.Po vyčistí nespravovaných zdrojů by mělo Dispose zavolat metodu GC.SuppressFinalize, aby mohlo uvolňování paměti vědět, že Finalize již nebude volána. To minimalizuje potřebu dalšího uvolňování paměti a zkracuje životnost objektu.
Jak vyřešit porušení
Pro napravení porušení tohoto pravidla je zapotřebí implementovat IDisposable.
Kdy potlačit upozornění
Je bezpečné potlačit varování tohoto pravidla, pokud typ neodkazuje na nespravovaný zdroj.Není-li tomu tak, není vhodné toto upozornění potlačovat, jelikož selhání při implementaci IDisposable může způsobit nedostupnost nebo nedostatečné využití nespravovaného zdroje.
Příklad
Následující příklad ukazuje typ, který implementuje IDisposable pro vyčištění nespravovaného zdroje.
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);
}
}
}
Související pravidla
CA2115: Volejte GC.KeepAlive při použití nativních zdrojů
CA1816: Volejte správně GC.SuppressFinalize
CA2216: Uvolnitelné typy by měly deklarovat finalizační metodu
CA1001: Typy, které vlastní uvolnitelné pole by měly být uvolnitelné
Viz také
Další zdroje
Vymazání nespravovaných prostředků
Implementing Finalize and Dispose to Clean Up Unmanaged Resources