CA1049: Typy, które posiadają natywne zasoby powinny być usuwalne
TypeName |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
Kategoria |
Microsoft.Design |
Zmiana kluczowa |
Niekluczowa |
Przyczyna
Typ odwołuje się do pola IntPtr, pola UIntPtr, lub pola HandleRef, ale nie implementuje IDisposable.
Opis reguły
Regułą zakłada, że pola IntPtr, UIntPtr, i HandleRef przechowują wskaźniki do niezarządzanych zasobów.Typy, które przydzielają niezarządzane zasoby powinny implementować IDisposable aby umożliwić wywołującym zwolnienie tych zasobów na żądanie oraz skrócenie czasu istnienia obiektów, które zawierają zasoby.
Zalecanym wzorcem projektowania dla oczyszczania niezarządzanych zasobów jest dostarczenie jawnych i niejawnych środków, zwalniania zasobów odpowiednio za pomocą metody Object.Finalize i metody IDisposable.Dispose.Moduł zbierający elementy bezużyteczne wywołuje metodę Finalize obiektu w pewnym nieokreślonym czasie po określeniu obiektu jako nieosiągalny.Po wywołaniu Finalize, dodatkowe działania modułu zbierającego elementy bezużyteczne są wymagane aby zwolnić obiekt.Metoda Dispose umożliwia wywołującemu jawnie zwolnić zasoby na żądanie wcześniej niż mogłyby zostać zwolnione, jeśli zostałoby pozostawione modułowi zbierającemu elementy bezużyteczne.Po jej wyczyszczeniu niezarządzanych zasobów Dispose powinna wywołać metodę GC.SuppressFinalize metody powiadamiają moduł zbierający elementy bezużyteczne, że metoda Finalize nie musi juz zostać wywołana; Eliminuje to potrzebę dodatkowego usuwania elementów bezużytecznych i skraca okres istnienia obiektu.
Jak naprawić naruszenia
Aby naprawić naruszenie tej zasady, należy zaimplementować IDisposable.
Kiedy pomijać ostrzeżenia
Można bezpiecznie pominąć ostrzeżenie od tej reguły, jeśli typ nie odwołuje się do żadnego niezarządzanego zasobu.W przeciwnym razie nie należy pomijać ostrzeżenia od tej reguły, ponieważ na brak implementacji IDisposable może spowodować, że zasoby niezarządzane staną się niedostępne lub nie zostaną w pełni wykorzystane.
Przykład
Poniższy przykład pokazuje typ, który implementuje IDisposable, aby zwolnić zasób niezarządzany.
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);
}
}
}
Powiązane reguły
CA2115: Wywołaj GC.KeepAlive gdy używasz zasobów natywnych
CA1816: Wywołaj poprawnie GC.SuppressFinalize
CA2216: Typy usuwalne powinny deklarować finalizator
CA1001: Typy, które posiadają pola usuwalne, powinny być usuwalne
Zobacz też
Inne zasoby
Oczyszczanie zasobów niezarządzanych
Implementing Finalize and Dispose to Clean Up Unmanaged Resources