Sdílet prostřednictvím


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