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çã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
Outros recursos
Implementing Finalize and Dispose to Clean Up Unmanaged Resources