IDisposable GC.SuppressFinalize (this) localização
-
03-07-2019 - |
Pergunta
Eu uso um modelo de implementação IDisposable padrão (padrão) para o meu código.
trecho:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool isDisposing)
{
if (!this.disposed)
{
if (isDisposing)
{
//cleanup managed resources
}
//cleanup unmanaged resources
this.disposed = true;
}
}
A minha pergunta: porque é que a chamada "GC.SuppressFinalize (this)" no método público Descarte? Eu colocaria "GC.SuppressFinalize (this)" no "se (isDisposing)" seção do método protegido, após a eliminação recursos gerenciados.
Como esta:
protected virtual void Dispose(bool isDisposing)
{
if (!this.disposed)
{
if (isDisposing)
{
//cleanup managed resources
GC.SuppressFinalize(this);
}
//cleanup unmanaged resources
this.disposed = true;
}
}
Solução
Eu suponho que é um caso claro de molde do projeto padrão.
Sua classe abstrata é projetado para cuidar de todas as tarefas importantes / necessários (Aqui, GC.SuppressFinalize (this)), e permitindo uma classe derivada para substituir apenas algumas parte do código.
Existem 2 casos aqui:
Trecho 1, SuppressFinalize, em Descarte
Trecho 2, SuppressFinalize, em Dispose (true)
Aqui, trechos 1, garante que GC.SuppressFinalize é sempre executado. Enquanto trecho 2, folhas a execução de GC.SuppressFinalize à mercê de classe derivada .
Assim, colocando GC.SuppressFinalize, no método Dispose, você como um designer de sua classe sempre certificar-se de que, independentemente de qualquer código escrito por classes derivadas, GC.SuppressFinalize será executado.
Este é apenas o benefício de escrever SuppressFinalize em Descarte em vez de Dispose (true).
Outras dicas
O método Dispose(bool isDisposing)
não faz parte do IDisposable
interface.
Você normalmente chamar Dispose(true)
do seu Dispose
método e Dispose(false)
do seu finalizador, como um fallback no caso em que o objeto não tiver sido já eliminados chamada.
SuppressFinalize
diz o GC que não há é necessidade de chamar finalizador do seu objeto, presumivelmente porque toda a sua limpeza foi feito quando Dispose
foi chamado.
Se você não tem um finalizador na sua classe, então você não precisa SuppressFinalize
chamada em tudo, já que não há finalizador para suprimir!
Joe Duffy tem algumas grandes diretrizes sobre a eliminação, finalização, coleta de lixo etc .
Eu acho que qualquer disposição poderia ter sido escolhido, mas provavelmente eles queriam enfatizar "colocar todo o código deallocation neste método" no método Dispose protegido, assim que colocar o outro artefato de descarte (finalização Suprimindo) em outro lugar.
Além disso, suponha que uma classe derivada tinha uma outra razão para chamar o método Dispose protegido, mas ainda queria finalização a ocorrer (por qualquer motivo imaginado, eu não sei).
código Causa .Dispose é quando conseguiu (o código) descarta o objeto optando, assim, fora da finalização. As pessoas costumam criar outra rota para Dispose (bool disposing) através de um finaliser ea chamada não faria qualquer sentido para o finaliser a fazer.
A idéia é que seu código de limpeza só deve ser chamado uma vez. No entanto, existem dois pontos de entrada: o método Dispose
e finalizadores objeto. Quando Dispose
é chamado, você optar por finalização para que seu código de limpeza só é chamado uma vez. O código aqui pode ilustrá-la melhor.
Citação:
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources itself, but leave the other methods
// exactly as they are.