Inicio > Programacion > Utilizando objetos IDisposable

Utilizando objetos IDisposable

sábado, 16 de marzo de 2024 Dejar un comentario Ir a comentarios

Esto no está relacionado con el juego, pero al ver a tanta gente escribiendo código en los foros que se parece a esto:

Stream stream = storageContainer.CreateFile("MyFile.txt");
StreamWriter writer = new StreamWriter(stream);
writer.Write("Stuff");
writer.Close();
stream.Close();

Me estremezco al ver eso.


IDisposable es una interfaz que libera los recursos o manejadores nativos y que casi siempre se implementa para garantizar que los recursos nativos se liberen correctamente y de manera determinista. Si alguno de los códigos provocaba una excepción, tenías el riesgo de no liberar los recursos necesarios hasta ese punto. A lo mejor verías que se liberen cuando se produzca una recolección de basura (GC- Garbage collection) y en el peor de los casos que no se limpien en absoluto.

Ahora, la mayoría de la gente responderá con «pero hay tan poco allí, ¿que podría originar una excepción?» Y eso es válido para este ejemplo, pero un montón de cosa por hacer, mucho más allí. Cosas como la serialización (o deserialización) de los objetos, analizar cadenas como números, y así sucesivamente. Hay un montón de lugares en los archivos de E/S, Estado de grabando/cargando, y otras manipulaciones stream pueden lanzar error, por lo que siempre es mejor estar en el lado de la seguridad en lugar de terquedad.

Cada vez que un tipo implementa IDisposable, debe ser su pista para aprovechar la declaración «using». En un caso lamentable, la palabra clave «using» no sólo se utiliza para la inclusión de espacios de nombres, sino también para la determinación del alcance de los objetos IDisposable para que se garantizen ser eliminados. Para volver a utilizar el ejemplo anterior, esta es la forma correcta de escribirlo:

using (Stream stream = storageContainer.CreateFile("MyFile.txt"))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        writer.Write("Stuff");
    }
}

Esto no sólo ayudará al alcance de tus objetos para evitar el uso de los objetos stream o writer fuera de sus respectivos bloques, pero eso significa que incluso si el código en el medio del bloque «using» produce una excepción, los objetos creados en las declaraciones «using» están garantizados para ser eliminados. Básicamente, el compilador toma el código anterior y lo convierte en lo siguiente:

{
    Stream stream = storageContainer.CreateFile("MyFile.txt");
    try
    {
        StreamWriter writer = new StreamWriter(stream);

        try
        {
            writer.Write("Stuff");
        }
        finally
        {
            if (writer != null)
                ((IDisposable)writer).Dispose();
        }
    }
    finally
    {
        if (stream != null)
            ((IDisposable)stream).Dispose();
    }
}

(Y sí, las llaves adicionales son intencionales y se utilizan con el ámbito objeto del «stream» para que no se puedan utilizar fuera del bloque «using».)

Como puedes ver este este código es mucho más seguro que el primer fragmento, ya que elimina la posibilidad de no eliminar los objetos y por lo tanto se asegura de que los recursos nativos se liberen correctamente cuando se espera que se produzca el próximo GC o cuando su aplicación se cierra.

Así que por favor, si usted se encuentra escribiendo un código similar al del primer fragmento de código, por favor, deje de hacer eso y empiece a «utilizar» correctamente los objetos IDisposable. 🙂

Comparte y diviertete:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • BlinkList
  • Blogosphere
  • Live
  • Meneame
  • MSN Reporter
  • MySpace
  • RSS
  • Suggest to Techmeme via Twitter
  • Technorati
  • LinkedIn
  • email
  • FriendFeed
  • PDF
  • Reddit
  • Wikio IT
  • Add to favorites
  • blogmarks
Top Footer