Freigeben über


CA2115: GC.KeepAlive beim Verwenden nativer Ressourcen aufrufen.

Element Wert
RuleId CA2115
Category Microsoft.Security
Unterbrechende Änderung Nicht unterbrechend

Ursache

Eine Methode, die in einem Typ mit einem Finalizer deklariert ist, verweist auf ein System.IntPtr- oder System.UIntPtr-Feld, ruft jedoch nicht System.GC.KeepAlive auf.

Hinweis

Diese Regel wurde als veraltet markiert. Weitere Informationen finden Sie unter Veraltete Regeln.

Regelbeschreibung

Die Garbage Collection finalisiert Objekte, auf die keine Verweise mehr im verwalteten Code vorhanden sind. Nicht verwaltete Verweise auf Objekte verhindern die Garbage Collection nicht. Diese Regel erkennt Fehler, die auftreten können, wenn eine nicht verwaltete Ressource freigegeben wird, während sie in nicht verwaltetem Code noch verwendet wird.

Diese Regel nimmt an, dass die Felder IntPtr und UIntPtr Zeiger auf nicht verwaltete Ressourcen speichern. Da der Zweck eines Finalizers darin besteht, nicht verwaltete Ressourcen freizugeben, geht die Regel davon aus, dass der Finalizer die nicht verwaltete Ressource freigibt, auf die die Zeigerfelder verweisen. Diese Regel nimmt auch an, dass die Methode auf das Zeigerfeld verweist, um die nicht verwaltete Ressource an nicht verwalteten Code zu übergeben.

Behandeln von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, fügen Sie der KeepAlive-Methode einen Aufruf hinzu, der die derzeitige Instanz (this in C# und C++) als Argument übergibt. Positionieren Sie den Aufruf nach der letzten Codezeile, wo das Objekt vor der Garbage Collection geschützt werden muss. Unmittelbar nach dem Aufruf KeepAlive von gilt das Objekt erneut als bereit für die Garbage Collection, sofern keine verwalteten Verweise darauf vorhanden sind.

Wann sollten Warnungen unterdrückt werden?

Diese Regel trifft einige Annahmen, die zu False Positives führen können. In den folgenden Fällen können Warnungen aus dieser Regel können ohne Risiko unterdrückt werden:

  • Der Finalizer gibt den Inhalt des Felds IntPtr oder UIntPtr, auf das von der Methode verwiesen wird, nicht frei.

  • Die Methode übergibt das Feld IntPtr oder UIntPtr nicht an nicht verwalteten Code.

Überprüfen Sie sorgfältig andere Nachrichten, bevor Sie sie ausschließen. Diese Regel erkennt Fehler, die schwer zu reproduzieren und zu debuggen sind.

Beispiel

Im folgenden Beispiel schließt BadMethod keinen Aufruf von GC.KeepAlive ein und verstößt daher gegen die Regel. GoodMethod enthält den korrigierten Code.

Hinweis

Dieses Beispiel besteht aus Pseudocode. Obwohl der Code kompiliert und ausgeführt wird, wird die Warnung nicht ausgelöst, da keine nicht verwaltete Ressource erstellt oder freigegeben wird.

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 ...
      }
      
   }

}

Siehe auch