Udostępnij za pośrednictwem


CA2115: Wywołaj GC.KeepAlive gdy używasz zasobów natywnych

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Kategoria

Microsoft.Security

Zmiana dzielenia

Bez dzielenia

Przyczyna

Metody zadeklarowane w typu z finalizatorów odwołuje się do IntPtr lub UIntPtr polu, ale nie wywołuje GC.KeepAlive.

Opis reguły

Kończenie znajdujących obiektu kolekcji Garbage, jeśli brak odwołań do niego w kodzie zarządzanym.Niezarządzany odwołania do obiektów nie uniemożliwiają wyrzucania elementów bezużytecznych.Ta reguła wykryje błędy, które mogą wystąpić, ponieważ niezarządzanego zasobu jest zatwierdzony podczas jest wciąż używany kod niezarządzany.

Zakłada się, że ta reguła IntPtr i UIntPtr pól przechowywania wskaźników niezarządzanych zasobów.Ponieważ celem finalizatorów zwolnić zasoby niezarządzanego, reguła zakłada, że finalizatorów zwolni niezarządzanego zasobu wskazywanej przez kursor pól.Ta reguła założono również, że metoda odwołuje się do pola wskaźnik do przekazania do niezarządzanego kodu niezarządzanego zasobu.

Jak naprawić naruszenia

Aby naprawić naruszenie tej zasady, dodać wywołanie KeepAlive do metody, przekazując bieżące wystąpienie (this w C# i C++) jako argumentu.Umieść wywołanie po ostatnim wierszu kodu, gdzie obiekt musi być chroniony przed wyrzucania elementów bezużytecznych.Natychmiast po wywołaniu KeepAlive, obiekt ponownie uznaje gotowy do wyrzucania elementów bezużytecznych, przy założeniu, że istnieją nie zarządzane odwołania do niego.

Kiedy pomija ostrzeżenia

Niektórych założeń, które mogą prowadzić do fałszywie sprawia, że ta reguła.Ostrzeżenie od tej reguły można pominąć bezpiecznie, jeśli:

  • Finalizatorów nie zwolni zawartość IntPtr lub UIntPtr pole odwołuje się metody.

  • Metoda nie przekaże IntPtr lub UIntPtr pola do kodu niezarządzanego.

Uważnie przejrzyj inne wiadomości przed wyłączając je.Ta reguła wykryje błędy, które są trudne do odtworzenia i debugowania.

Przykład

W poniższym przykładzie BadMethod nie zawiera wywołanie GC.KeepAlive , a zatem narusza reguły.GoodMethodzawiera kod poprawiony.

[!UWAGA]

W tym przykładzie jest pseudo-code, chociaż Kod kompiluje i wykonuje, ostrzeżenie nie jest uruchamiany, ponieważ niezarządzanego zasobu nie zostanie utworzony lub zwolnione.

using System;

namespace SecurityRulesLibrary
{
   class IntPtrFieldsAndFinalizeRequireGCKeepAlive
   {
      private IntPtr unmanagedResource;

      IntPtrFieldsAndFinalizeRequireGCKeepAlive()
      {
         GetUnmanagedResource (unmanagedResource);
      }

      // The finalizer frees the unmanaged resource.
      ~IntPtrFieldsAndFinalizeRequireGCKeepAlive()
      {
         FreeUnmanagedResource (unmanagedResource);
      }

      // Violates rule:CallGCKeepAliveWhenUsingNativeResources.  
      void BadMethod()
      {
         // Call some unmanaged code.
         CallUnmanagedCode(unmanagedResource);
      }

      // Satisfies the rule. 
      void GoodMethod()
      {
         // Call some unmanaged code.
         CallUnmanagedCode(unmanagedResource);
         GC.KeepAlive(this);
      }

      // Methods that would typically make calls to unmanaged code. 
      void GetUnmanagedResource(IntPtr p)
      {
        // Allocate the resource ...
      }
      void FreeUnmanagedResource(IntPtr p)
      {
        // Free the resource and set the pointer to null ...
      }
      void CallUnmanagedCode(IntPtr p)
      {
        // Use the resource in unmanaged code ...
      }

   }

}

Zobacz też

Informacje

GC.KeepAlive

IntPtr

Object.Finalize

UIntPtr

Inne zasoby

Implementing Finalize and Dispose to Clean Up Unmanaged Resources