CA1049: Typy vlastních nativní zdrojů by měly být na jedno použití
TypeName |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
Kategorie |
Microsoft.Design |
Narušující změna |
Nenarušující |
Příčina
Typ odkazuje na pole System.IntPtr a na pole System.UIntPtr nebo na pole System.Runtime.InteropServices.HandleRef, ale neimplementuje System.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: GC volání.Udržovací při použití nativních zdrojů
CA1816: GC volání.Funkce SuppressFinalize správně
CA2216: Na jedno použití typů by měla deklarovat finalizačních metod
CA1001: Typy, které vlastní jednorázových polí by mělo být na jedno použití
Viz také
Referenční dokumentace
Implementing Finalize and Dispose to Clean Up Unmanaged Resources