Chamar GC.KeepAlive ao usar os recursos nativo

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Category (Categoria)

Microsoft.segurança

Quebrando alterar

Não separável

Causa

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

Descrição da regra

Lixo coleção Finaliza um objeto, não se houver nenhum mais referências a ele em código gerenciado.Não gerenciadas referências a objetos não impedirão o lixo coleção.Essa regra detecta erros que podem ocorrer porque 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 é disponível recursos não gerenciados, a regra pressupõe que o finalizador será disponível o recurso não gerenciado apontado pelo ponteiro campos.Esta regra também pressupõe que o método faz referência 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 dessa regra, adicione uma telefonar para KeepAlive para o método, passando o corrente (instânciathis no C++ e translation from VPE for Csharp) sistema autônomo argumento. Posicione a telefonar após a última linha do código onde o objeto deve ser protegido contra lixo coleção.Imediatamente após a telefonar para KeepAlive, o objeto será considerado novamente pronto para a coleta de lixo supondo que não haja nenhuma referência a ele gerenciado.

Quando suprimir avisos

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

  • O finalizador não liberar o Sumário do IntPtr ou UIntPtr campo referido pelo método.

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

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

Exemplo

Neste exemplo, BadMethod viola a regra. GoodMethod conté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 Finalize e Dispose para Apagar up recursos não gerenciados

GC.KeepAlive

System.IntPtr

Object.Finalize

System.UIntPtr