CA2115: Chame GC.Ao usar os recursos nativos de KeepAlive

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

<strong>Categoria</strong>

Microsoft.Security

Alteração significativa

Não separável

Causa

Um método declarado em um tipo com um finalizador faz referência a uma System.IntPtr ou System.UIntPtr campo, mas não não chamar GC.KeepAlive.

Descrição da regra

Coleta de lixo Finaliza um objeto, se não houver nenhum mais referências a ele em código gerenciado. Não gerenciadas referências a objetos não impedem a coleta de lixo. Essa regra detecta erros que podem ocorrer devido um recurso não gerenciado está sendo finalizado enquanto ainda estiver sendo usado no código não gerenciado.

Esta regra pressupõe que IntPtr e UIntPtr os campos armazenam os ponteiros para os recursos não gerenciados. Como a finalidade de um finalizador é liberar recursos não gerenciados, a regra pressupõe que o finalizador liberará o recurso não gerenciado apontado por campos de ponteiro. Esta regra também pressupõe que o método está fazendo referência ao campo de ponteiro para passar o recurso não gerenciado para código não gerenciado.

Como corrigir violações

Para corrigir uma violação desta regra, adicione uma chamada para KeepAlive para o método, passando a instância atual (this em C# e C++) como argumento. Posicione a chamada após a última linha do código onde o objeto deve ser protegido de coleta de lixo. Imediatamente após a chamada para KeepAlive, o objeto será considerado novamente pronto para coleta de lixo, supondo que não há nenhuma referência de gerenciado para o proprietário.

Quando suprimir avisos

Essa regra faz algumas suposições que podem levar a falsos positivos. Com segurança, você pode suprimir um aviso de que essa regra se:

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

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

Revise cuidadosamente as outras mensagens antes de excluí-las. Essa regra detecta erros que são difíceis de reproduzir e depurar.

Exemplo

Neste exemplo, BadMethod viola a regra. GoodMethodcontém o código corrigido.

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

Implementando finalizar e Dispose para limpeza de recursos não gerenciados

GC.KeepAlive

System.IntPtr

Object.Finalize

System.UIntPtr