System.Runtime.InteropServices.SafeHandle classe

Este artigo fornece observações complementares à documentação de referência para essa API.

A SafeHandle classe fornece finalização crítica de recursos de manipulação, evitando que os identificadores sejam recuperados prematuramente pela coleta de lixo e sejam reciclados pelo sistema operacional para fazer referência a objetos não intencionais não gerenciados.

Porquê o SafeHandle?

Embora as substituições ao método permitam a limpeza de recursos não gerenciados quando um objeto está sendo coletado lixo, em algumas circunstâncias, objetos finalizáveis podem ser recuperados pela coleta de lixo durante a Object.Finalize execução de um método dentro de uma chamada de chamada de plataforma. Se um finalizador liberar o identificador passado para essa chamada de chamada de plataforma, isso poderá levar a lidar com corrupção. O identificador também pode ser recuperado enquanto seu método é bloqueado durante uma chamada de chamada de plataforma, como durante a leitura de um arquivo.

Mais importante, como o Windows recicla agressivamente os identificadores, um identificador pode ser reciclado e apontar para outro recurso que pode conter dados confidenciais. Isso é conhecido como um ataque de reciclagem e pode potencialmente corromper dados e ser uma ameaça à segurança.

O que o SafeHandle faz

A SafeHandle classe simplifica vários desses problemas de vida útil do objeto e é integrada à plataforma invoke para que os recursos do sistema operacional não sejam vazados. A SafeHandle classe resolve problemas de tempo de vida do objeto atribuindo e liberando identificadores sem interrupção. Ele contém um finalizador crítico que garante que o identificador seja fechado e seja executado durante descargas inesperadas AppDomain , mesmo nos casos em que a chamada de chamada de chamada da plataforma é assumida como estando em um estado corrompido.

Porque SafeHandle herda do CriticalFinalizerObject, todos os finalizadores não críticos são chamados antes de qualquer um dos finalizadores críticos. Os finalizadores são chamados em objetos que não estão mais vivos durante o mesmo passe de coleta de lixo. Por exemplo, um objeto pode executar um FileStream finalizador normal para liberar dados armazenados em buffer existentes sem o risco de o identificador ser vazado ou reciclado. Essa ordenação muito fraca entre finalizadores críticos e não críticos não se destina ao uso geral. Ele existe principalmente para ajudar na migração de bibliotecas existentes, permitindo que essas bibliotecas usem SafeHandle sem alterar sua semântica. Além disso, o finalizador crítico e qualquer coisa que ele chame, como o SafeHandle.ReleaseHandle() método, devem estar em uma região de execução restrita. Isso impõe restrições sobre qual código pode ser escrito no gráfico de chamada do finalizador.

As operações de invocação da plataforma incrementam automaticamente a contagem de referência de identificadores encapsulados por um SafeHandle e os decrementam após a conclusão. Isso garante que a alça não será reciclada ou fechada inesperadamente.

Você pode especificar a propriedade do identificador subjacente ao construir SafeHandle objetos fornecendo um valor para o ownsHandle argumento no construtor de SafeHandle classe. Isso controla se o objeto liberará o identificador depois que o SafeHandle objeto for descartado. Isso é útil para alças com requisitos de vida útil peculiares ou para consumir uma alça cuja vida útil é controlada por outra pessoa.

Classes derivadas de SafeHandle

SafeHandle é uma classe wrapper abstrata para identificadores do sistema operacional. Derivar dessa classe é difícil. Em vez disso, use as Microsoft.Win32.SafeHandles classes derivadas no namespace que fornecem identificadores seguros para o seguinte: