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;
    }
}
Foi útil?

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. 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top