El .RED recolector de basura, finalmente, liberar memoria, pero lo que si desea que la memoria de inmediato? ¿Qué código que usted necesita para su uso en una clase MyClass llamar

MyClass.Dispose()

y liberar todo el espacio utilizado por las variables y objetos en MyClass?

20 Comentarios

  1. 101

    IDisposable no tiene nada que ver con la liberación de memoria. IDisposable es un patrón para liberar no administrado de los recursos, y la memoria es, en definitiva, un recurso administrado.

    Los enlaces que apuntan a la GC.Collect() son la respuesta correcta, a pesar de que el uso de esta función generalmente se desaconseja por Microsoft .NETO de la documentación.

    Edición: después de Haber ganado una considerable cantidad de karma para esta respuesta, siento cierta responsabilidad de elaborar, no sea un recién llegado a la .RED de gestión de recursos da la impresión equivocada.

    Dentro de una .NETA proceso, hay dos tipos de recurso-administrado y no administrado. «Administrado», significa que el tiempo de ejecución es en el control de los recursos, mientras que «no administrado» significa que es responsabilidad del programador. Y realmente hay sólo una clase de la gestión de los recursos que nos importa en .RED hoy — la memoria. El programador le dice que el tiempo de ejecución para asignar memoria y después de que el tiempo de ejecución de averiguar cuando la memoria liberada. El mecanismo que .NET que se utiliza para este propósito se llama la recolección de basura y usted puede encontrar un montón de información acerca de la GC en el internet simplemente mediante el uso de Google.

    Para los otros tipos de recursos .NET no sabe nada acerca de la limpieza de ellos, de forma que tiene que depender de un programador para hacer lo correcto. Para ello, la plataforma proporciona al programador de tres herramientas:

    1. La interfaz IDisposable y el «uso de la» declaración en VB y C#
    2. Finalizadores
    3. La IDisposable patrón, como el implementado por muchos BCL clases

    La primera de ellas permite al programador eficiente de adquirir un recurso, utilizar y, a continuación, suelte todo dentro de un mismo 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

    Si «AcquireResource» es un método de fábrica que (por ejemplo) abre un archivo y «Tire» cierra automáticamente el archivo, a continuación, este código no puede dejar escapar un archivo de recursos. Pero la memoria de la «tmp» objeto en sí podrían ser asignados. Eso es porque la interfaz IDisposable tiene absolutamente ninguna relación con el recolector de basura. Si usted hizo desea asegurarse de que la memoria fue liberado, su única opción sería llamar a GC.Collect() a la fuerza de una recolección de basura.

    Sin embargo, no se puede enfatizar lo suficiente que esta no es probablemente una buena idea. Por lo general es mucho mejor dejar que el recolector de elementos no utilizados de lo que fue diseñado, que es la gestión de la memoria.

    ¿Qué sucede si el recurso está siendo utilizado por un largo período de tiempo, de tal forma que su vida se cruza varios métodos? Claramente, el «uso» de la declaración no es aplicable, por lo que el programador tendría que manualmente llamada «Tire» cuando él o ella se hace con el recurso. ¿Y qué pasa si el programador olvida? Si no hay ninguna reserva, a continuación, el proceso o el equipo finalmente se ejecute fuera de cualquier recurso no está siendo adecuadamente liberado.

    Que es donde los finalizadores vienen en. Un finalizador es un método en su clase que tiene una relación especial con el recolector de basura. El GC de las promesas de que, antes de liberar la memoria para un objeto de ese tipo — le dará con el finalizador una oportunidad para hacer algún tipo de limpieza.

    Así, en el caso de un archivo, teóricamente, no se necesita cerrar el archivo manualmente en todos. Podemos esperar hasta que el recolector de basura llega a ella y, a continuación, deje que el finalizador de hacer el trabajo. Por desgracia, esto no funciona bien en la práctica debido a que el recolector de basura se ejecuta no-determinista. El archivo puede permanecer abierta considerablemente más largo que el programador espera. Y si una cantidad suficiente de archivos se mantienen abiertas, el sistema puede fallar al intentar abrir un archivo adicional.

    Para la mayoría de los recursos, queremos tanto de estas cosas. Queremos un convenio para ser capaz de decir «vamos a hacer con este recurso» y queremos asegurarnos de que hay al menos una oportunidad para la limpieza a suceder de forma automática si nos olvidamos de hacerlo manualmente. Ahí es donde el «IDisposable» patrón entra en juego. Esta es una convención que permite IDispose y un finalizador para jugar bien juntos. Usted puede ver cómo el patrón de las obras por mirar el la documentación oficial para IDisposable.

    Línea de base: Si lo que realmente quieres hacer es asegurarse de que la memoria se libera, entonces IDisposable y finalizadores no le ayudará. Pero la interfaz IDisposable es parte de una muy importante que todos los .NET programadores deben entender.

    • Yo sólo quería señalar que hay un tema de la terminología con esta pregunta y sus respuestas. Todos ustedes están hablando de liberar/eliminación de los objetos; es decir, las instancias de una clase. Una clase es el tipo en sí, el código asociado -procedimientos, funciones, propiedades, etc.- y compartido (estático) datos de la clase. La liberación de la memoria u otros recursos a partir de una clase en sí es mucho más difícil que en una instancia, ya que supone la descarga de todo el dominio de aplicación de la vida de la clase a, junto con su asamblea y otras clases relacionadas. Por supuesto que no es algo que uno normalmente quieren hacer.
    • fue agradable si hubiera incluido algún código, ejemplos.
  2. 22

    Sólo se puede disponer de las instancias que implementan la interfaz IDisposable.

    Para forzar un recoger la basura para liberar el (no administrado) memoria de inmediato:

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

    Normalmente esto es una mala práctica, pero por ejemplo, hay un error en el x64 versión de el .NET framework que hace la GC comportan de un modo extraño en algunos escenarios, y entonces es posible que desee hacer esto. No sé si el error ha sido resuelto aún. ¿Alguien sabe?

    Para disponer de una clase de hacerlo:

    instance.Dispose();

    o como este:

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

    que se va a traducir en tiempo de compilación a:

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

    Puede implementar la interfaz 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;
        }
    }
    • Esto es a lo largo de las líneas de lo que estoy tratando de averiguar. Si usted tiene el código administrado… MyClass que desea indicar que el hecho de con. ¿Usted simplemente asignar null? lo que estás diciendo es igual a la implementación de IDisposable? No es fácil explicar lo que estoy tratando de preguntar. Básicamente tengo un bucle que las noticias de una clase en cada bucle quiero indicar que he terminado con ella. Te lo dejo como está o asignar null, o implementar esto. uisng declaración sin todos los demás bits (finiliser). vacía método dispose. O es que esta mal.
    • sólo debe implementar IDisposable si la clase se mantiene en otras cosas que son IDisposable (y la invocación de su método Dispose (), y cuando estás utlilizing cosas como los recursos no administrados. Si usted es preocuparse por GC costo en un bucle, tal vez usted debe buscar en lo que es un tipo de valor (struct) o de alguna manera la reutilización de la instancia cambiando la forma en que funciona.
  3. 19

    Las respuestas a esta pregunta tiene más que un poco confundido.

    El título de la pregunta acerca de la eliminación, pero luego dice que quiere la memoria de inmediato.

    .Net es administrado, lo que significa que cuando usted escribe .Net las aplicaciones que usted no necesita preocuparse acerca de la memoria directamente, el costo es que usted no tiene control directo sobre la memoria.

    .Net decide cuando es el mejor para limpiar y liberar la memoria, no como el .Net programador.

    La Dispose es una manera de decir .Neta que termines con algo, pero que en realidad no liberar la memoria hasta que sea el mejor momento para hacerlo.

    Básicamente .Net realmente recoger la memoria cuando es más fácil para hacerlo – es muy buena en decidir cuando. A menos que usted está escribiendo algo muy intensivo de memoria que normalmente no es necesario anular (esto es parte de la razón de juegos no son a menudo escritos .Net todavía se necesita un control completo)

    En .Net se puede utilizar GC.Collect() a la fuerza para de inmediato, pero que es casi siempre una mala práctica. Si .Neta no se limpian sin embargo, eso significa que no es un momento especialmente bueno para hacerlo.

    GC.Collect() recoge los objetos que .Net identifica como hacer con. Si usted no ha desechado a un objeto que necesita .Net puede decidir mantener ese objeto. Esto significa que GC.Collect() sólo es efectiva si se implementa correctamente su desechables instancias.

    GC.Collect() es no un reemplazo para el uso correcto de IDisposable.

    Para Disponer de memoria y no están directamente relacionados, pero que no necesitan ser. Correctamente disponer hará que su .Net aplicaciones más eficientes y, por tanto, el uso de menos memoria, aunque.


    99% del tiempo .Neto el siguiente es el mejor práctica:

    Regla 1: Si usted no tiene que lidiar con nada no administrado o que implementa IDisposable entonces no hay que preocuparse de Disponer.

    Regla 2: Si usted tiene una variable local que implementa IDisposable asegúrese de que usted deshacerse de ella en el ámbito actual:

    //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();
    }

    Regla 3: Si una clase tiene una propiedad o variable miembro que implementa IDisposable, a continuación, que la clase debe implementar IDisposable demasiado. En que clase de método Dispose usted también puede deshacerse de su IDisposable propiedades:

    //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
        }
    }

    Esto no es realmente completa, es por eso que el ejemplo está sellado. Heredar de las clases puede necesitar para observar la siguiente regla…

    Regla 4: Si una clase utiliza un no administrado de recursos, a continuación, implementar IDispose y agregar un finaliser.

    .Net no puede hacer nada con el no administrado de recursos, por lo que ahora estamos hablando de la memoria. Si usted no limpia, puede obtener una pérdida de memoria.

    El método Dispose necesita tratar con tanto administrado y no administrado recursos.

    La finaliser es un cierre de seguridad – asegura que si alguien la crea y la instancia de la clase y no disponer el ‘peligroso’ no administrado recursos todavía se puede limpiar .Net.

    ~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 Disponer que lleva una bandera booleana:

    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;
    }

    Tenga en cuenta que una vez que todo esto es en lugar de otro código administrado la creación de una instancia de la clase sólo puede tratarlo como a cualquier otro IDisposable (Reglas 2 y 3).

  4. 14

    Sería apropiado mencionar también que disponer no siempre se refieren a la memoria? Me deshago de recursos una de las referencias a archivos con más frecuencia de la memoria. GC.Collect() se relaciona directamente con el CLR recolector de basura y puede o no liberar memoria (en el Administrador de Tareas). Es probable que el impacto de su aplicación en forma negativa (por ejemplo, rendimiento).

    Al final del día ¿por qué quieres la memoria de inmediato? Si hay presión en la memoria de otra parte, el OS recibirá usted de memoria en la mayoría de los casos.

  5. 6

    Echa un vistazo a este artículo

    La aplicación de la Dispose patrón, IDisposable, y/o un finalizador tiene absolutamente nada que ver con cuando la memoria se presenta reclamado; en su lugar, tiene todo que ver con decir la GC cómo recuperar esa memoria. Cuando llamar a Dispose() de ninguna manera de interactuar con el GC.

    La GC sólo se ejecutará cuando se determina la necesidad (que se llama presión de memoria) y entonces (y sólo entonces) se cancela la asignación de memoria para los objetos sin usar y compacto, el espacio de la memoria.

    Que podría llamar a la GC.Collect() pero de verdad que no tiene a menos que haya una muy buena razón (que es casi siempre «Nunca»). Cuando la fuerza de un fuera-de-banda ciclo de colección como esta usted realmente hacer que la GC para hacer más trabajo y en última instancia, puede acabar afectando a su rendimiento de las aplicaciones. Para la duración de la GC de la colección de su ciclo de aplicación está realmente en un estado de congelación…más GC ciclos que se ejecutan, más el tiempo de su aplicación pasa congelado.

    También hay algunos nativos de llamadas a la API Win32 que usted puede hacer para liberar a su conjunto de trabajo, pero incluso los que debe evitarse a menos que haya una muy buena razón para hacerlo.

    Toda la premisa detrás de un gargbage recogidos en tiempo de ejecución es que usted no necesita preocuparse (como mucho) acerca de cuando el tiempo de ejecución asigna/cancela la asignación de memoria real, usted sólo tiene que preocuparse por asegurarse de que el objeto sabe cómo limpiar después de sí mismo cuando se le preguntó.

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

    entonces usted puede hacer algo como esto

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

    o

    using (MyClass instance = new MyClass())
    {
    
    }
    //instance will be disposed right here as it goes out of scope
  7. 3

    Explicación completa por Joe Duffy en «Disponer, la Finalización, y la Gestión de los Recursos«:

    Anteriormente en el .NET Framework
    toda la vida, los finalizadores fueron consistentemente
    se refiere a como los destructores de C#
    los programadores. Como podemos ser más inteligentes, con más de
    tiempo, estamos tratando de llegar a un acuerdo
    con el hecho de que el método Dispose
    en realidad es más equivalente a la de C++
    destructor (determinista)
    , mientras que el
    finalizador es algo totalmente
    independiente (no determinista)
    . El hecho de
    que C# prestado el destructor de C++
    sintaxis (es decir, ~T()) seguro que había al menos
    un poco que ver con el desarrollo de
    este nombre inapropiado.

  8. 3

    Escribí un resumen de los Destructores y Disponer y recolección de Basura en http://codingcraftsman.wordpress.com/2012/04/25/to-dispose-or-not-to-dispose/

    Para responder a la pregunta original:

    1. No trate de manejar su memoria
    2. Disponer no es acerca de la gestión de la memoria, se trata de no administrado la gestión de los recursos
    3. Finalizadores son una parte innata de la Dispose patrón y en realidad se ralentiza en memoria de la liberación de los objetos administrados (como tienen que ir a la Finalización de la cola, a menos que ya Disponer d)
    4. GC.Recopilar es malo ya que hace algunos objetos de corta duración parece que se requiere de más tiempo y por lo ralentiza de ser recogidos.

    Sin embargo, GC.Recopilamos puede ser útil si usted tuvo un rendimiento crítico de la sección de código y quería reducir la probabilidad de la Recolección de Basura se ralentice. Llama usted a eso antes.

    Por encima de todo, no es un argumento en favor de este patrón:

    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);

    Pero la principal respuesta es que la Recolección de Basura sólo funciona a menos que usted lío con ella!

  9. 2

    Realmente no se puede forzar a un GC para limpiar un objeto cuando quieras, aunque hay formas de forzar a correr, nada de lo que dice es limpiar el todos los objetos que quieren o esperan. Lo mejor es llamar a dispose en un try catch ex finalmente desechar end try (VB.NET ruiz) en el camino. Pero Disponer es para la limpieza de los recursos del sistema (memoria, asas, bases de datos, conexiones, etc asignados por el objeto, de manera determinista. Deseche no (y no pueden) limpiar la memoria utilizada por el objeto en sí, sólo la GC puede hacer eso.

  10. 1

    Este artículo tiene bastante sencillo tutorial. Sin embargo, tener para llamar a la GC en lugar de dejar que siga su curso natural, generalmente es un signo de mal diseño/gestión de la memoria, especialmente si no limitados recursos se consumen (conexiones, controles, nada más de lo que normalmente conduce a la aplicación de IDisposable).

    Cuál es la causa de que usted necesita hacer esto?

  11. 1

    Lo siento, pero la respuesta seleccionada aquí es incorrecta. Como algunas personas han afirmado, posteriormente, Disponer y aplicar IDisposable no tiene nada que ver con liberar la memoria asociada con una .Clase NET. Es, principalmente, y que tradicionalmente se utiliza para liberar recursos no administrados, tales como identificadores de archivo, etc.

    Mientras que su aplicación puede llamar a la GC.Collect() para intentar forzar una colección por el recolector de basura esto sólo será realmente tener un efecto sobre aquellos elementos que están en la correcta generación de nivel en el freachable cola. Así que es posible que si has eliminado todas las referencias al objeto de que todavía puede ser un par de llamadas a la GC.Collect() antes de que la memoria real es liberado.

    No dices en tu pregunta de por QUÉ sientes la necesidad de liberar la memoria de inmediato. Entiendo que a veces puede haber circunstancias inusuales, pero en serio, en código administrado casi siempre es mejor dejar que el tiempo de ejecución de acuerdo con la gestión de memoria.

    Probablemente el mejor consejo si usted piensa que su código es el uso de memoria más rápida que la GC es liberar a continuación, usted debe revisar su código para asegurarse de que no hay objetos que no son necesarios se hace referencia en ninguna de las estructuras de datos que tengas en la estática de los miembros de la etc. También intenta evitar las situaciones donde usted tiene circular de referencias a objetos como es posible que estos no pueden ser liberados, ya sea.

  12. 1

    @Keith,

    Estoy de acuerdo con todas las reglas, excepto el #4. La adición de un finalizador debe hacerse sólo bajo circunstancias muy específicas. Si una clase utiliza los recursos no administrados, los que deben ser limpiados en su Dispose(bool) de la función. Esta misma función sólo debe de limpieza de los recursos administrados cuando bool es cierto. La adición de un finalizador añade una complejidad costo para el uso de su objeto como cada vez que se crea una nueva instancia también debe ser colocado en la finalización de la cola, la cual es revisada cada vez que el GC se ejecuta un ciclo de recolección. Efectivamente, esto significa que el objeto sobrevive a un ciclo de generación/más de lo que debería para el finalizador se puede ejecutar. El finalizador no debe ser pensado como una «red de seguridad».

    La GC sólo se ejecutará un ciclo de recogida, si se determina que no hay suficiente memoria disponible en el Gen0 montón para realizar la siguiente asignación, a menos que te «ayuda» llamando a la GC.Collect() para forzar un fuera-de-banda de la colección.

    La línea de fondo es que, no importa qué, la GC sólo sabe cómo liberar recursos llamando al método Dispose (y posiblemente el finalizador si uno está implementado). Es hasta ese método para «hacer lo correcto» y limpiar todos los recursos no administrados utilizado e instruir a cualquier otros recursos gestionados a llamar a su método Dispose. Es muy eficiente en lo que hace y puede auto-optimizar en gran medida el tiempo que no es ayudado por fuera de banda de la colección de ciclos. Que siendo dicho, corto de llamar a la GC.Recoger de forma explícita que no tiene ningún control sobre cuándo y en qué orden los objetos serán eliminados de la memoria y libertad.

  13. 0

    Si MyClass implementa IDisposable que usted puede hacer precisamente eso.

    MyClass.Dispose();

    Las mejores prácticas en C# es:

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

    Como que envuelve al disponer en un intento por último, y asegura que nunca ha perdido.

  14. 0

    Si usted no desea (o no puede) implementar IDisposable en su clase, puede forzar la recolección de basura como este (pero lento) –

    GC.Collect();
  15. 0

    Interfaz IDisposable es realmente para las clases que contienen los recursos no administrados. Si la clase no contiene los recursos no administrados, ¿por qué necesidad para liberar recursos antes de que el recolector de basura no? De lo contrario, sólo asegúrese de que su objeto es instanciado tan tarde como sea posible y queda fuera del ámbito de aplicación tan pronto como sea posible.

  16. 0

    Usted puede tener determinista de la destrucción de objetos en c++

    Usted nunca quiere llamar a la GC.Recoger, se mete con el ajuste automático del recolector de elementos no utilizados para detectar la presión de la memoria y en algunos casos hacer otra cosa que aumentar la generación actual de cada objeto en el heap.

    Para aquellos publicación de IDisposable respuestas. Llamar a un método Dispose no destruir un objeto como el autor de la pregunta describe.

  17. 0

    @Keith:

    IDisposable es por recursos administrados.

    Finalisers son para los recursos no administrados.

    Lo siento, pero eso está mal. Normalmente, el finalizador no hace nada. Sin embargo, si el disponer patrón ha sido correctamente implementado, el finalizador intenta invocar Dispose.

    Dispose tiene dos trabajos:

    • Libre a los recursos no administrados, y
    • libre anidada de los recursos gestionados.

    Y aquí su declaración entra en juego, porque es cierto que mientras finalizar, un objeto debe nunca tratar de liberar a anidada recursos administrados como estos ya han sido liberados. Aún así, debe libres de recursos no administrados sin embargo.

    Aún, los finalizadores no tienen ningún trabajo de otros que llamar Dispose y decirle que no toque los objetos administrados. Dispose, cuando se llama manualmente (o a través de Using), estará libre de todos los recursos no administrados y pasar el Dispose mensaje a objetos anidados (y la base de los métodos de la clase), pero esto nunca libre de cualquier (administrado) de la memoria.

  18. 0

    Konrad Rudolph – sí, normalmente el finaliser no hace nada. Usted no debe aplicar a menos que usted está tratando con recursos no administrados.

    Entonces, cuando se implementan, se utiliza Microsoft deshacerse de patrón (como ya se ha descrito)

    • public Dispose() llamadas protected Dispose(true) – ofertas con ambos administrados y no administrados recursos. Llamar Dispose() debería suprimir finalización.

    • ~Finalize llamadas protected Dispose(false) – se trata de los recursos no administrados solamente. Esto evita que la memoria no administrada fugas si no llamar la public Dispose()

    ~Finalize es lento, y no debe ser utilizado a menos que usted tiene los recursos no administrados para tratar con.

    Recursos administrados no pueden pérdida de memoria, sólo pueden desperdiciar recursos para la aplicación actual y retardar su recolección de basura. Los recursos no administrados pueden perder, y ~Finalize es la mejor práctica para asegurarse de que no.

    En cualquiera de los casos using es la mejor práctica.

  19. 0

    @Curt Hagenlocher – que la de atrás a delante. Yo no tengo ni idea de por qué tantas personas han votado hasta cuando es malo.

    IDisposable es para administrado recursos.

    Finalisers son para no administrado recursos.

    Mientras que sólo el uso de los recursos gestionados tanto @Jon Limjap y yo estamos del todo correcto.

    Para las clases que utilizan recursos no administrados (y tenga en cuenta que la gran mayoría de los .Net clases no) Patrik respuesta integral y las mejores prácticas.

    Evitar el uso de GC.Recoger – es una manera lenta de acuerdo con los recursos administrados, y no hace nada con el no administrado queridos, a menos que han construido correctamente su ~Finalizadores.


    Me he quitado el moderador de comentarios de la pregunta original, en línea con https://stackoverflow.com/questions/14593/etiquette-for-modifying-posts

  20. 0

    En respuesta a la pregunta original, con la información dada hasta ahora por el cartel original, es 100% seguro de que él no sabe lo suficiente acerca de la programación en .NET incluso a ser la respuesta: el uso de GC.Collect(). Yo diría que es el 99,99% de probabilidades de que él realmente no necesita el uso de GC.Collect() en todos, como la mayoría de los carteles han señalado.

    La respuesta correcta se reduce a ‘Vamos a la GC a hacer su trabajo. Período. Usted tiene otras cosas de que preocuparse. Pero es posible que desee considerar si y cuando usted debe deshacerse de o limpieza de objetos específicos, y si usted necesita para implementar IDisposable y posiblemente Finalizar en su clase».

    Respecto de Keith post y en su Regla #4:

    Algunos carteles son confusos regla de 3 y la regla 4. Keith regla 4 es absolutamente correcto, unequivocately. Es la regla de los cuatro que no necesita de edición en todos. Yo sería un poco reformular algunas de sus otras normas para hacerlas más claras, pero son esencialmente correctas si se analiza correctamente, y realmente leer todo el post para ver cómo se amplía en ellos.

    1. Si tu clase no utilizar un recurso no administrado Y también nunca se instancia un objeto de una clase que utiliza, directamente o en última instancia, un objeto no administrado (es decir, una clase que implementa IDisposable), entonces no habría necesidad de su clase para implementar IDisposable sí mismo, o incluso de la llamada .disponer en nada. (En tal caso, es tonto pensar que en realidad se NECESITA para liberar inmediatamente a la memoria con un forzado de la GC, de todos modos.)

    2. Si su clase utiliza un recurso no administrado, O crea otro objeto que a su vez implementa IDisposable, la clase debe:

      a) disponer/liberación de estos de inmediato en un contexto local en el que fueron creadas, O…

      b) implementar IDisposable en el patrón recomendado dentro de Keith post, o un par de miles de lugares en el internet, o en, literalmente, a unos 300 libros por ahora.

      b.1) por otra parte, si (b), y es un recurso no administrado que ha sido abierto, tanto IDisposable Y Finalizar SIEMPRE DEBE ser implementado, por Keith Regla #4.

      En este contexto, Finalizar absolutamente ES una red de seguridad en un sentido: si alguien crea TU IDisposable objeto que utiliza un recurso no administrado, y no llamar a dispose, después de Finalizar es la última oportunidad para el objeto para cerrar el recurso no administrado correctamente.

      (Finalizar debe hacer esto llamando a Disponer de tal manera que el método Dispose salta sobre la liberación de nada, PERO el recurso no administrado. Alternativamente, si el objeto del método Dispose SE llama correctamente, por lo que crea una instancia del objeto, entonces los dos pases en el Dispose llamado a todos los IDisposable objetos a los que se ha instanciado, Y libera los recursos no administrados correctamente, finaliza con una llamada a reprimir al Finalizar en el objeto, lo que significa que el impacto del uso de Finalizar se reduce si su objeto es eliminado adecuadamente por la persona que llama. Todos estos puntos están incluidos en Keith post, por CIERTO.)

      b.2) SI su clase es sólo la aplicación de IDisposable porque necesita esencialmente pase de Disponer de un IDisposable objeto instanciado, entonces no implementan un método Finalize en su clase en ese caso. Finalizar es para manejar el caso de que AMBOS Deseche nunca fue llamado por lo que crea una instancia del objeto, Y un recurso no administrado fue utilizado que todavía inédito.

    En definitiva, sobre Keith post, es totalmente correcta, y que el post es la más correcta y completa respuesta, en mi opinión. Se pueden usar algunos de resumen de las declaraciones que algunos consideran » mal » o el objeto a, pero su post completo se expande el uso de Finalizar por completo, y él es absolutamente correcto. Asegúrese de leer su post completo antes de saltar sobre una de las reglas o declaraciones preliminares en su post.

    • Gracias por señalar que yo no sé lo suficiente acerca de la programación en .Net y por lo tanto no se debe dar una respuesta (incluso sin tomar en cuenta la alimentación de stackoverflow cuando todavía estaba empezando)! Deduzco que era tarde en la noche en que se escribió la respuesta y normalmente lo hace mejor.
    • Es su nombre TAMBIÉN Jon Galloway o OP?

Dejar respuesta

Please enter your comment!
Please enter your name here