Compartilhar via


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

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Category (Categoria)

Microsoft.Security

A última alteração

Não quebrando

Faz com que

Um método declarado em um tipo com um finalizer referencia um campo de System.IntPtr ou de System.UIntPtr , mas não chama GC.KeepAlive.

Descrição da regra

Coleta de lixo finaliza um objeto se não há mais referências a ele no código gerenciado.Referências não gerenciado para objetos não impedem coleta de lixo.Esta regra detectar erros que podem ocorrer porque um recurso não gerenciado está sendo encerrado quando utilizados ainda em código não gerenciado.

Esta regra pressupõe que IntPtr e os campos de UIntPtr armazenam ponteiros para recursos não gerenciados.Porque o objetivo de um finalizer está liberar recursos não gerenciados, a regra pressupõe que o finalizer irá liberar o recurso não gerenciado apontado pelos campos do ponteiro.Esta regra também pressupõe que o método está referenciando o 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 de esta regra, adicione um KeepAlive a chamada para o método, passando a instância atual (this em C# e C++) como o argumento.Posicionar a chamada depois da linha de código para a última onde o objeto deve ser protegido de coleta de lixo.Imediatamente após a chamada a KeepAlive, o objeto é considerado novamente pronto para coleta de lixo que assume que há não gerenciado referência a ele.

Quando suprimir avisos

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

  • O finalizer não liberar os conteúdos do campo de IntPtr ou de UIntPtr referenciado pelo método.

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

Examine cuidadosamente outras mensagens antes excluindo de eles.Esta regra detectar erros que são difíceis de reproduzir e depurar.

Exemplo

Em o exemplo, BadMethod não inclui uma chamada para GC.KeepAlive e portanto não viola a regra.GoodMethod contém o código corrigido.

ObservaçãoObservação

Este exemplo é pseudo-código embora o código compila e executa, o aviso não é 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

Implementing Finalize and Dispose to Clean Up Unmanaged Resources

GC.KeepAlive

System.IntPtr

Object.Finalize

System.UIntPtr