Pergunta

A .NET coletor de lixo irá, eventualmente, liberar memória, mas o que se pretende que a memória de volta imediatamente?Qual o código que você precisa para usar em uma classe MyClass para chamar

MyClass.Dispose()

e liberta todo o espaço usado por variáveis e objetos na MyClass?

Foi útil?

Solução

IDisposable não tem nada a ver com liberar memória.IDisposable é um padrão para libertar não gerenciado recursos-e a memória é bastante definitivamente um recurso gerenciado.

Os links que apontam para o GC.Recolher() são a resposta correta, embora o uso desta função é geralmente desencorajado pela Microsoft .NET documentação.

Editar: Tendo ganho uma quantidade substancial de karma para esta resposta, eu sinto uma certa responsabilidade para elaborar sobre isso, para que um recém chegado .LÍQUIDA de recursos de gerenciamento de obter a impressão errada.

Dentro de um .LÍQUIDO de processo, existem dois tipos de recursos -- gerenciados e não gerenciados."Gerenciado" significa que o tempo de execução está no controle do recurso, enquanto "unmanaged" significa que é responsabilidade do programador.E não há realmente apenas um tipo de recurso gerenciado que nos preocupamos com o em .NET hoje -- memória.O programador diz que o tempo de execução para alocar memória e depois que o tempo de execução para descobrir quando a memória pode liberado.O mecanismo .NET usa para este efeito é chamado de a coleta de lixo e você pode encontrar muita informação sobre GC na internet, basta usar o Google.

Para os outros tipos de recursos .LÍQUIDO não sabe nada sobre limpá-los e por isso tem que confiar no que o programador fazer a coisa certa.Para este fim, a plataforma dá ao programador três ferramentas:

  1. A interface IDisposable e a "utilizar" a instrução no VB e C#
  2. Finalizadores
  3. O IDisposable padrão seguido por muitos BCL classes

A primeira delas permite que o programador eficiente de adquirir um recurso, use-a e, em seguida, liberá-lo, tudo dentro do mesmo método.

using (DisposableObject tmp = DisposableObject.AcquireResource()) {
    // Do something with tmp
}
// At this point, tmp.Dispose() will automatically have been called
// BUT, tmp may still a perfectly valid object that still takes up memory

Se "AcquireResource" é um método de fábrica, que (por exemplo) abre um arquivo e "Descarte" fecha automaticamente o arquivo e, em seguida, este código não pode vazamento de um arquivo de recurso.Mas a memória para o "tmp" objeto em si pode muito bem ainda estar alocado.Isso porque a interface IDisposable não tem absolutamente nenhuma conexão com o coletor de lixo.Se você fiz queremos garantir que a memória foi liberada, sua única opção seria a chamada para a GC.Collect() para forçar uma coleta de lixo.

No entanto, ele não pode ser salientado o suficiente de que esta não é provavelmente uma boa idéia.Em geral, é muito melhor deixar que o coletor de lixo, fazer o que ele foi projetado para fazer, que é a de gerenciar a memória.

O que acontece se o recurso está sendo usado por um longo período de tempo, de modo que a sua vida útil atravessa vários métodos?Claramente, a "utilizar" a instrução não é mais aplicável, portanto, o programador teria que manualmente chamada de "Descarte" quando ele ou ela é feita com o recurso.E o que acontece se o programador se esquece?Se não houver uma reversão, em seguida, o processo ou o computador poderá, eventualmente, executar fora de qualquer tipo de recurso ainda não está sendo liberada corretamente.

Que é de onde vêm os finalizadores em.Um finalizador é um método na sua classe que tem uma relação especial com o coletor de lixo.O GC promessas que -- antes de liberar a memória para qualquer objeto do tipo -- ele vai dar o finalizador uma chance de fazer algum tipo de limpeza.

Assim, no caso de um arquivo, que, teoricamente, não precisa fechar o arquivo manualmente em todos os.Nós podemos apenas esperar até que o coletor de lixo chega nele e, em seguida, deixe o finalizador de fazer o trabalho.Infelizmente, isso não funciona bem na prática porque o coletor de lixo é executado não-determinística.O arquivo pode permanecer aberto consideravelmente maior do que o programador espera.E se um número suficiente de arquivos são mantidos abertos, o sistema poderá falhar quando tentar abrir um arquivo adicional.

Para a maior parte dos recursos, queremos ambas as coisas.Queremos uma convenção para ser capaz de dizer "estamos a fazer com este recurso agora" e nós queremos ter certeza de que há pelo menos alguma chance para que a limpeza aconteça automaticamente se nós se esqueça de fazê-lo manualmente.Que é onde o "IDisposable" padrão entra em jogo.Esta é uma convenção que permite IDispose e um finalizador para jogar bem juntos.Você pode ver como o padrão funciona observando o a documentação oficial de IDisposable.

Linha inferior: Se o que você realmente quer fazer é apenas certifique-se de que a memória é liberada e, em seguida, IDisposable e finalizadores não vai ajudar você.Mas a interface IDisposable é parte de um padrão extremamente importante que todos .NET programadores devem entender.

Outras dicas

Você só pode dispor de instâncias que implementam a interface IDisposable.

Para forçar um lixo recolher para liberar o (não gerenciado) de memória imediatamente:

GC.Collect();  
GC.WaitForPendingFinalizers();

Isso normalmente é uma prática ruim, mas há, por exemplo, um erro no x 64-versão do os .NET framework que faz com que o GC se comportar de forma estranha em alguns cenários, e, em seguida, você pode querer fazer isso.Eu não sei se o problema tiver sido resolvido ainda.Alguém conhece?

Para dispor de uma classe de você fazer isso:

instance.Dispose();

ou assim:

using(MyClass instance = new MyClass())
{
    // Your cool code.
}

o que será traduzido em tempo de compilação para:

MyClass instance = null;    

try
{
    instance = new MyClass();        
    // Your cool code.
}
finally
{
    if(instance != null)
        instance.Dispose();
}

Você pode implementar a interface IDisposable como este:

public class MyClass : IDisposable
{
    private bool disposed;

    /// <summary>
    /// Construction
    /// </summary>
    public MyClass()
    {
    }

    /// <summary>
    /// Destructor
    /// </summary>
    ~MyClass()
    {
        this.Dispose(false);
    }

    /// <summary>
    /// The dispose method that implements IDisposable.
    /// </summary>
    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// The virtual dispose method that allows
    /// classes inherithed from this one to dispose their resources.
    /// </summary>
    /// <param name="disposing"></param>
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Dispose managed resources here.
            }

            // Dispose unmanaged resources here.
        }

        disposed = true;
    }
}

As respostas a esta pergunta tem mais do que um pouco confuso.

O título pergunta sobre a alienação, mas, em seguida, diz que eles querem memória de volta imediatamente.

.Net é gerenciado, o que significa que quando você escreve .Net aplicativos que você não precisa de se preocupar com a memória diretamente, o custo é de que você não tem controle direto sobre a memória.

.Net decide que é melhor limpo e livre de memória, não como .Net codificador.

O Dispose é uma maneira de dizer .Net que você é feito com algo, mas não, na verdade, liberar a memória até que é o melhor momento para fazer isso.

Basicamente .Net, na verdade, coletar a memória de volta quando é mais fácil para ele fazê - lo- é muito bom em decidir quando.A menos que você esteja escrevendo algo muito uso intensivo de memória, você normalmente não precisa dominá-lo (esta é parte da razão por que os jogos muitas vezes não estão escritas .Net ainda, eles precisam de um controle completo)

Em .Net, você pode usar GC.Collect() para forçá-lo imediatamente, mas que é quase sempre uma má prática.Se .Net não limpa-lo, ainda que significa que não é um momento particularmente bom para ele para fazer isso.

GC.Collect() pega os objetos .Net identifica como feito com.Se você ainda não descartados, de um objeto que necessita .Net pode decidir manter o objeto.Isto significa que GC.Collect() só é eficaz se você implementar corretamente o seu descartáveis instâncias.

GC.Collect() é não uma substituição para usar corretamente os IDisposable.

Então, Descarte e a memória não estão diretamente relacionados, mas não precisa ser.Corretamente o descarte vai fazer o seu .Net apps mais eficiente e, portanto, utilizar menos memória embora.


99% do tempo .Net seguintes é a melhor prática:

Regra 1: Se você não lidar com qualquer coisa não gerenciado ou que implementa IDisposable então não se preocupe em Descartar.

Regra 2: Se você tem uma variável local que implementa IDisposable certifique-se de que você se livrar dele no escopo atual:

//using is best practice
using( SqlConnection con = new SqlConnection("my con str" ) )
{
    //do stuff
} 

//this is what 'using' actually compiles to:
SqlConnection con = new SqlConnection("my con str" ) ;
try
{
    //do stuff
}
finally
{
    con.Dispose();
}

Regra 3: Se uma classe tem uma propriedade ou variável de membro que implementa IDisposable, em seguida, que a classe deve implementar IDisposable também.Em que classe o método Dispose você também pode dispor do seu IDisposable propriedades:

//rather basic example
public sealed MyClass :
   IDisposable
{   
    //this connection is disposable
    public SqlConnection MyConnection { get; set; }

    //make sure this gets rid of it too
    public Dispose() 
    {
        //if we still have a connection dispose it
        if( MyConnection != null )
            MyConnection.Dispose();

        //note that the connection might have already been disposed
        //always write disposals so that they can be called again
    }
}

Isto não é realmente completo, que é por isso que o exemplo é selado.Herdar classes podem precisar observar a seguinte regra...

Regra 4: Se uma classe usa um não gerenciado de recursos, em seguida, implementar IDispose e adicionar um finaliser.

.Líquido não pode fazer nada com o não gerenciado de recursos, de modo que agora estamos a falar de memória.Se você não limpá-lo você pode obter um vazamento de memória.

O método Dispose precisa lidar com ambos gerenciado e não gerenciado recursos.

O finaliser é um trinco de segurança - garante que, se alguém cria e instância de sua classe e não descartar o 'perigoso' não gerenciado recursos ainda podem ser limpos pelo .Líquida.

~MyClass()
{
    //calls a protected method 
    //the false tells this method
    //not to bother with managed
    //resources
    this.Dispose(false);
}

public void Dispose()
{
    //calls the same method
    //passed true to tell it to
    //clean up managed and unmanaged 
    this.Dispose(true);

    //as dispose has been correctly
    //called we don't need the 

    //'backup' finaliser
    GC.SuppressFinalize(this);
}

Finalmente, esta sobrecarga de Descarte que leva um sinalizador booleano:

protected virtual void Dispose(bool disposing)
{
    //check this hasn't been called already
    //remember that Dispose can be called again
    if (!disposed)
    {
        //this is passed true in the regular Dispose
        if (disposing)
        {
            // Dispose managed resources here.
        }

        //both regular Dispose and the finaliser
        //will hit this code
        // Dispose unmanaged resources here.
    }

    disposed = true;
}

Note que uma vez que isso é tudo no lugar outro código gerenciado a criação de uma instância de sua classe pode apenas tratar como qualquer outra IDisposable (Regras 2 e 3).

Seria apropriado mencionar também que alienar nem sempre se referir a memória?Eu dispor de recursos tais referências a arquivos com mais frequência do que a memória.GC.Recolher() se relaciona diretamente com o CLR coletor de lixo e podem ou não livre de memória (no Gerenciador de Tarefas).É, provavelmente, o impacto de sua aplicação em negativo maneiras (por exemplo, desempenho).

No final do dia, por que você quer a memória de volta imediatamente?Se há pressão de memória de outro lugar SO vai tirar você de memória na maioria dos casos.

Dê uma olhada neste artigo

Implementando o padrão de Descarte, IDisposable, e/ou um finalizador tem absolutamente nada a ver com quando a memória é recuperada;em vez disso, ele tem tudo a ver com o ato de dizer o GC como para recuperar essa memória.Quando você chamar Dispose() você não está em forma de interagir com o GC.

O GC só será executada quando ele determina a necessidade de (chamado de pressão de memória) e então (e só então) vai desalocar a memória para objetos não utilizados e compacto, o espaço de memória.

Você poderia chamada de GC.Recolher (), mas você realmente não deve, a menos que haja um muito boa razão (que é quase sempre "Nunca").Quando você força um fora-de-banda ciclo de coleta de como este que você realmente fazer com que o GC para fazer mais trabalho e, em última análise, pode acabar prejudicando o seu desempenho de aplicações.Para a duração do GC ciclo de recolha de sua aplicação é, na verdade, em um estado congelado...o mais GC ciclos de executar, mais tempo a sua aplicação passa congelado.

Existem também algumas espécies chamadas de API do Win32 que você pode fazer para liberar seu conjunto de trabalho, mas mesmo aqueles que devem ser evitados, a menos que haja um muito uma boa razão para fazê-lo.

A premissa por trás de um gargbage coletados de tempo de execução é que você não precisa se preocupar (tanto) sobre quando o tempo de execução aloca/desaloca memória real;você só precisa se preocupar, certificando-se o seu objeto sabe como limpar depois de si, quando solicitado.

public class MyClass : IDisposable
{
    public void Dispose()
    {
       // cleanup here
    }
}

em seguida, você pode fazer algo como isto

MyClass todispose = new MyClass();
todispose.Dispose(); // instance is disposed right here

ou

using (MyClass instance = new MyClass())
{

}
// instance will be disposed right here as it goes out of scope

Explicação completa por Joe Duffy no "Dispor, Finalização e Gestão de Recursos":

Anteriormente no .NET Framework vida, finalizadores foram consistentemente referido como destruidores C# programadores.Como nos tornar mais inteligentes sobre em tempo, estamos a tentar chegar a um acordo com o fato de que o Método Dispose é realmente mais equivalente ao C++ destruidor (determinístico), enquanto a finalizador é algo completamente separado (não determinístico).O fato de que o C# emprestado o destruidor C++ sintaxe (por exemplo,~T()) certamente tinha pelo menos um pouco a ver com o desenvolvimento de este equívoco.

Eu escrevi um resumo dos processos de destruição e Descarte e a coleta de Lixo no http://codingcraftsman.wordpress.com/2012/04/25/to-dispose-or-not-to-dispose/

Para responder a pergunta inicial:

  1. Não tente gerenciar sua memória
  2. Descarte não é sobre o gerenciamento de memória, é sobre a gestão de recursos não gerenciados
  3. Finalizadores são inatas parte do padrão de Descarte e, na verdade, diminuir a memória liberação de objetos gerenciados (como eles têm de ir para a Finalização da fila, a menos que já Dispor d)
  4. GC.Coletar é ruim como ele faz algumas de curta duração, os objetos parecem ser necessários por mais tempo e assim diminui-los a ser recolhidos.

No entanto, a GC.Recolher poderia ser útil se você teve um desempenho seção crítica de código e queria reduzir a probabilidade de Coleta de Lixo diminuir a velocidade.Você chama isso antes.

Em cima disso, há um argumento em favor desse padrão:

var myBigObject = new MyBigObject(1);
// something happens
myBigObject = new MyBigObject(2);
// at the above line, there are temporarily two big objects in memory and neither can be collected

vs

myBigObject = null; // so it could now be collected
myBigObject = new MyBigObject(2);

Mas a principal resposta é que a Coleta de Lixo funciona, a menos que você mexer com ele!

Você realmente não pode forçar um GC para limpar um objeto quando você quer, apesar de existirem maneiras para forçá-lo a executar, nada diz que é limpar a todo o objeto que você deseja/espera.É melhor chamar dispose em um try catch ex finalmente dispor de fim de tentar (VB.NET rulz) forma.Mas o Descarte é para limpeza de recursos do sistema (memória, cabos, conexões a banco de dados, etc.alocados pelo objeto em forma determinista.Descarte não é (e não pode) limpar a memória usada pelo objeto em si, somente a GC pode fazer isso.

Este artigo tem uma relação muito direta passo a passo.No entanto, ter para chamar o GC em vez de deixá-lo tomar o seu curso natural é geralmente um sinal de mau design/gestão de memória, especialmente se não limitados recursos estão sendo consumidos (conexões, cabos, coisa que normalmente leva à implementação de IDisposable).

O que está fazendo com que você precisa para fazer isso?

Desculpe, mas a resposta selecionada, aqui está incorreta.Como algumas pessoas já declarou, posteriormente, Descartar e implementação de IDisposable não tem nada a ver com liberar a memória associada a um .NET classe.É, principalmente, e tradicionalmente usado para liberar recursos não gerenciados, tais como identificadores de arquivo etc.

Enquanto o seu aplicativo pode chamar de GC.Recolher() para tentar forçar uma coleção de pelo coletor de lixo, isso só vai realmente ter um efeito sobre os itens que estão na correta geração do freachable fila.Portanto, é possível que se você tiver desmarcado todas as referências para o objeto que ele ainda pode ser um par de convites para o GC.Recolher() antes que a memória é liberada.

Você não dizer na sua pergunta, PORQUE você sente a necessidade de liberar memória imediatamente.Eu entendo que, às vezes, pode haver circunstâncias incomuns, mas a sério, em código gerenciado é quase sempre melhor deixar que o tempo de execução de lidar com a gestão de memória.

Provavelmente o melhor conselho que se você acha que o seu código está usando a memória mais rápido do que o GC está liberando, em seguida, você deve rever o seu código para garantir que não há objetos que não são mais necessários são referenciados em quaisquer estruturas de dados que você tem em torno de mentir em membros estáticos, etc.Também tente evitar situações onde você tem objeto circular referências como é possível que estas não podem ser libertado um.

@Keith,

Concordo com todas as suas regras, exceto #4.A adição de um finalizador deve ser feito somente sob circunstâncias muito específicas.Se uma classe usa recursos não gerenciados, esses devem ser limpos no seu Dispor(bool) função.Essa mesma função só deve limpeza de recursos gerenciados quando bool é verdadeiro.A adição de um finalizador que adiciona uma complexidade de custo para o uso de seu objeto como a cada vez que você criar uma nova instância ele também deve ser colocado na finalização da fila, o qual é verificada cada vez que o GC executa um ciclo de coleta.Efetivamente, isso significa que o objeto sobrevive a um ciclo de geração de mais tempo do que deveria para o finalizador pode ser executado.O finalizador não deve ser pensado como uma "rede de segurança".

O GC irá apenas executar um ciclo de coleta de quando determina que não há memória suficiente disponível no Gen0 pilha para executar a próxima repartição, a menos que você "ajuda" chamando o GC.Recolher() para forçar um fora-de-banda coleção.

A linha inferior é que, não importa o que, o GC só sabe a liberação de recursos por chamar o método Dispose (e, possivelmente, o finalizador se um é implementado).É até que o método para "fazer a coisa certa" e limpar quaisquer recursos não gerenciados usado e instruir quaisquer outros recursos gerenciados para chamar de seu método Dispose.Ele é muito eficiente no que faz e pode auto-otimizar o grande medida, contanto que ele não é ajudado por fora-de-banda ciclos de coleta.Dito isso, curto de chamar GC.Recolher explicitamente você não tem nenhum controle sobre quando e em que ordem os objetos serão eliminados da memória e liberado.

Se MyClass implementa IDisposable você pode fazer exatamente isso.

MyClass.Dispose();

Melhores práticas em C# é:

using( MyClass x = new MyClass() ) {
    //do stuff
}

Como que passará a depositá-lo em um try-finally e certifica-se de que ele nunca perdeu.

Se você não quer (ou não pode) implementar IDisposable em sua classe, você pode forçar a coleta de lixo como este (mas lento) -

GC.Collect();

IDisposable interface é realmente para as classes que contêm recursos não gerenciados.Se sua classe não contém recursos não gerenciados, por que você necessidade para liberar os recursos antes que o coletor de lixo não é?Caso contrário, apenas garantir que o seu objeto é instanciado o mais tarde possível e sai de escopo, como o mais rapidamente possível.

Você pode ter determinista destruição de objeto em c++

Você nunca quer chamar GC.Recolher, ele mexe com o auto-ajuste do coletor de lixo para detectar a pressão de memória e, em alguns casos, fazer nada além de aumentar a geração atual de cada objeto no heap.

Para aqueles que postaram IDisposable respostas.Chamar um método Dispose não destruir um objeto como o questionador descreve.

@Keith:

IDisposable é para gestão de recursos.

Finalisers são para recursos não gerenciados.

Desculpe, mas está errado.Normalmente, o finalizador não faz absolutamente nada.No entanto, se o padrão de descarte foi implementado corretamente, o finalizador tenta invocar Dispose.

Dispose tem dois trabalhos:

  • Livre recursos não gerenciados, e
  • livre aninhadas recursos gerenciados.

E aqui a sua instrução entra em jogo, porque é verdade que, enquanto finalizar, um objeto nunca deve tentar libertar aninhadas recursos gerenciados como estas podem já ter sido liberada.Ele ainda tem de higiene recursos não gerenciados embora.

Ainda, finalizadores ter nenhum trabalho diferente para chamar Dispose e dizer a ele para não tocar objetos gerenciados. Dispose, quando chamado manualmente (ou através de Using), deve liberar todos os recursos não gerenciados e passar o Dispose mensagem para objetos aninhados (e da base de dados de métodos de classe), mas isso vai nunca livre de qualquer (gerenciado) de memória.

Konrad Rudolph - sim, normalmente o finaliser não faz absolutamente nada.Você não deve implementá-lo, a menos que você está lidando com recursos não gerenciados.

Então, quando você fizer implementá-lo, você pode usar Microsoft padrão de descarte (como já descrito)

  • public Dispose() chamadas protected Dispose(true) - lida com recursos gerenciados e não gerenciados.Chamar Dispose() deve suprimir a finalização.

  • ~Finalize chamadas protected Dispose(false) - lida com recursos não gerenciados, apenas.Isso impede que não gerenciado vazamentos de memória se você não chamar o public Dispose()

~Finalize é lento, e não deve ser usado, a menos que você tiver recursos não gerenciados para lidar com eles.

Recursos gerenciados não pode vazamento de memória, eles só podem desperdiçar recursos para o aplicativo atual e diminuir a velocidade de coleta de lixo.Recursos não gerenciados, pode vazar, e ~Finalize é a melhor prática para garantir que não.

Em ambos os casos using é a melhor prática.

@Curt Hagenlocher - que é de trás para a frente.Eu não tenho nenhuma idéia de por que tantos tenham votado até quando ele está errado.

IDisposable é para gerenciado recursos.

Finalisers são para não gerenciado recursos.

Contanto que você usar apenas recursos geridos tanto @Jon Limjap e a mim, estão totalmente corretas.

Para classes que utilizam recursos não gerenciados (tenha em mente que a grande maioria dos .Net classes não) Patrik, a resposta é abrangente e melhores práticas.

Evitar o uso de GC.Recolher - é uma forma lenta de lidar com recursos geridos, e não fazer nada com não gerenciado queridos, a menos que você corretamente construiu o seu ~Finalizadores.


Eu removi o moderador comentário da pergunta original, em linha com https://stackoverflow.com/questions/14593/etiquette-for-modifying-posts

Em resposta à pergunta original, com as informações apresentadas até o momento, pelo autor, é 100% de certeza de que ele não conhece o suficiente sobre a programação .NET mesmo ser dada a resposta:o uso de GC.Recolher().Eu diria que é 99,99% de probabilidade de que ele realmente não precisa usar GC.Recolher() em tudo, como a maioria dos cartazes têm apontado.

A resposta correta se resume a " Deixe que o GC do seu trabalho.Período.Você tem outras coisas para se preocupar.Mas você pode querer considerar se, e quando o deve alienar ou limpar objetos específicos, e se você precisa implementar IDisposable e, possivelmente, Finalize sua classe".

Relação de Keith post e sua Regra #4:

Alguns cartazes são confusas regra de 3 e a regra 4.Keith regra 4 é absolutamente correto, unequivocately.É a única das quatro regras que não precisa de edição.Eu iria um pouco reformular algumas de suas outras regras para torná-los mais claros, mas eles são essencialmente correta, se você analisá-los corretamente, e, na verdade, leia o post inteiro para ver como ele se expande sobre eles.

  1. Se sua classe não é usar um recurso não gerenciado E ele também nunca instancia outro objeto de uma classe que utiliza, diretamente ou em última análise, um objeto não (por exemplo, uma classe que implementa IDisposable), então não seria necessário para a sua classe para implementar IDisposable em si, ou até mesmo chamar .dispor em qualquer coisa.(Nesse caso, é bobagem pensar que você realmente PRECISA imediatamente liberar memória com um forçado GC, de qualquer maneira.)

  2. Se a sua classe usa um recurso não gerenciado, OU instancia outro objeto que implementa IDisposable, em seguida, sua classe deve:

    a) dispor/release-los imediatamente em um contexto local em que foram criados, OU...

    b) implementar IDisposable no padrão recomendado dentro de Keith post, ou alguns milhares de lugares na internet, ou em, literalmente, cerca de 300 livros por agora.

    b.1) Além disso, se (b), e é um recurso não gerenciado que foi aberto, tanto IDisposable E Finalizar DEVE ser SEMPRE implementada, por Keith Regra #4.
    Neste contexto, Finalizar absolutamente É uma rede de segurança em um sentido:se alguém cria o SEU IDisposable objeto que usa um recurso não gerenciado, e eles não conseguem chamar dispose, em seguida, Finalizar é a última chance para o SEU objeto para fechar o recurso não gerenciado corretamente.
    (Finalizar deve fazer isso chamando Dispor de tal forma que o método Dispose ignora lançar nada, MAS o recurso não gerenciado.Em alternativa, se o objeto do método Dispose É chamado corretamente por qualquer que seja instanciado o objeto, em seguida, ele passa a Dispor de chamada para todas as IDisposable objetos que ele foi instanciado, E libera os recursos não gerenciados corretamente, terminando com uma chamada para suprimir a Finalizar no seu objeto, o que significa que o impacto do uso de Finalizar é reduzido se o objeto é descartado corretamente pelo chamador.Todos esses pontos estão incluídas no Keith post, BTW.)

    b.2) SE sua classe é apenas a implementação de IDisposable porque ele precisa, essencialmente, passar a Dispor de um IDisposable objeto que foi instanciado, não implementar um método Finalize, em sua classe, no caso.Finalize é para lidar com o caso que TANTO Dispor nunca foi chamado por qualquer que seja instanciado o objeto, E um recurso não gerenciado utilizou-se que, ainda não lançado.

Em suma, a relação de Keith post, ele está completamente correto, e esse post não é o mais correto e completo resposta, na minha opinião.Ele pode usar algumas curtas-mão declarações que alguns consideram "errado" ou o objeto, mas seu post completo expande o uso de Finalizar completamente, e ele está absolutamente correto.Certifique-se de ler seu post completamente antes de saltar em uma das regras preliminares ou declarações em seu post.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top