Compartilhar via


CA2115: chamar GC.KeepAlive durante o uso de recursos nativos

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Categoria

Microsoft.Security

Alteração Significativa

Sem Quebra

Causa

Um método declarado em um tipo com um finalizador refere a um campo de IntPtr ou de UIntPtr , mas não chama GC.KeepAlive.

Descrição da Regra

A coleta de lixo terminar um objeto se não houver mais referência a ele em código gerenciado.As referências a objetos não gerenciados não impedem a coleta de lixo.Esta regra detectar erros que podem ocorrer porque um recurso não gerenciado está sendo encerrado quando usados no código não gerenciado.

Esta regra supõe que IntPtr e os campos de UIntPtr armazena ponteiros para os recursos não gerenciados.Como o objetivo de um finalizador é liberar recursos não gerenciados, a regra presume que o finalizador libera os recursos não gerenciados apontado pelos campos do ponteiro.Esta regra também presume que o método faz referência ao campo do ponteiro para passar o recurso não gerenciados para código não gerenciado.

Como Corrigir Violações

Para corrigir uma violação desta regra, adicione uma chamada a KeepAlive ao método, passando a instância atual (this no C# e em C++) como o argumento.Posicione a chamada depois que a linha de código a última vez em que o objeto deve ser protegido de coleta de lixo.Imediatamente depois da chamada para KeepAlive, o objeto será considerado novamente pronto para coleta de lixo pressupondo que não há nenhuma referência a ela.

Quando Suprimir Alertas

Esta regra faz algumas suposições que podem resultar em falsos positivos.Você pode suprimir com segurança um aviso dessa regra se:

  • O finalizador não libera o conteúdo do campo de IntPtr ou de UIntPtr referenciado pelo método.

  • O método não transmite o campo de IntPtr ou de UIntPtr para código não gerenciado.

Revise cuidadosamente outras mensagens com exclusão antes delass.Esta regra detectar erros que são difíceis de reproduzir e depurar.

Exemplo

No exemplo a seguir, BadMethod não inclui uma chamada a GC.KeepAlive e não em virtude disso violará a regra.GoodMethod contém o código corrigido.

ObservaçãoObservação

Este exemplo é pseudocódigo embora o código cria e executa, o aviso não será acionado como um recurso não gerenciado não é criado ou não é liberado.

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

   }

}

Consulte também

Referência

GC.KeepAlive

IntPtr

Object.Finalize

UIntPtr

Outros recursos

Implementing Finalize and Dispose to Clean Up Unmanaged Resources