February 2009 - Artículos

"But nothing is perfect in God's perfect plan
He only gave us the good things so we'd understand
What life without them would be"
("Nothing is perfect", Neil Young, 1985)

Retomando el tema de un post anterior relacionado con los patrones try-finally y la conveniencia de su utilización para garantizar la devolución de los recursos que una aplicación solicita en un contexto local, llamaremos hoy la atención sobre un caso en el que la utilización de la sentencia using es problemática y del que se ha empezado a hablar sobre todo a raíz de la aparición de WCF (Windows Communication Foundation) con .NET 3.0.

Como seguramente ya sabe, la sentencia using permite construir un objeto que implementa la interfaz IDisposable, garantizando que al finalizar la ejecución del bloque que acompaña a la sentencia, sea de la manera que sea (normalmente o debido a una excepción), se hará una llamada al método Dispose del objeto, asegurando de esta forma la liberación de los recursos asociados a él. Un ejemplo típico de uso de using (valga la redundancia :-) podría ser el siguiente:

  using (var sr = new System.IO.StreamReader("DATA.TXT"))
  {
    Console.WriteLine(sr.ReadToEnd());
  }

La semántica de using determina que la sentencia anterior es equivalente a:

  var sr = new System.IO.StreamReader("DATA.TXT");
  try
  {
    Console.WriteLine(sr.ReadToEnd());
  }
  finally
  {
    sr.Dispose();
  }

Hasta aquí, todo genial; pero solo si asumimos que, según proponen las guías generales de diseño de clases de .NET, Dispose no lanza excepciones. Si Dispose puede lanzar excepciones, el using tiene dos problemas serios: a) en caso de que el código del bloque lance una excepción E1, y esa excepción desencadene otra excepción E2 en la llamada a Dispose, la segunda excepción ocultará a la primera ante el contexto de ejecución; b) independientemente de que el código del bloque lanzara o no excepción alguna, pero la llamada implícita a Dispose sí lo hiciera, el lugar de la excepción podría no ser evidente para un programador que examine el código fuente. En cualquiera de los casos, está claro que si Dispose lanzara una excepción las instrucciones que sigan a la instrucción using en el código no se ejecutarán.

La guía de diseño antes referenciada dice literalmente "Evite lanzar una excepción desde dentro de Dispose, excepto en situaciones críticas en las que el proceso contenedor esté corrupto" (no sé si la guía habrá cambiado algo en la reciente segunda edición de "Framework Design Guidelines", que aún no tengo). El caso es que esto no ocurre en el caso de los proxies de servicios WCF, cuyo método Dispose (al igual que su medio hermano Close) puede lanzar CommunicationObjectFaultedException. Esta página de MSDN alerta del hecho, y presenta la manera recomendada de trabajar con los proxies WCF. Dino Esposito también describe detalladamente la situación en el ejemplar nº 56 de dotNetManía.

¡Queda advertido!


Pop/rock tip: Neil Young es un cantante y guitarrista con más de 40 años de carrera, ya sea como miembro de bandas como Buffalo Springfield o Crosby, Stills, Nash & Young, en solitario o acompañado de su propia banda, Crazy Horse. Por el volumen e influencia de su obra,  All Music Gude lo sitúa en segundo lugar entre los intérpretes de su generación, solo por detrás de Bob Dylan. Su tema más conocido es "Heart of Gold", que la revista Rolling Stone colocó en el lugar 297 de las 500 mejores canciones de todos los tiempos.

 

Publicado por Octavio Hernández | 1 comment(s)
Archivado en: ,

"I hope you don't mind / That I put down in words
How wonderful life is while you're in the world."
("Your Song", Elton John, 1970)

"And if you can't be with the one you love
Love the one you're with"
("Love the One You're With", Crosby, Stills, Nash & Young, 1971)

Con un día de retraso, este post va destinado a desear a los lectores que hayáis pasado un feliz San Valentín en compañía de vuestros seres queridos.

Cierto es que aquí en España a este día no parece otorgársele una gran relevancia (al menos, no la que tiene en Cuba), y más de una vez he escuchado que se le llame jocosamente "El Día del Corte Inglés" (por cierto, puede leer sobre la relación entre Cuba y El Corte Inglés aquí). Tales bromas, por supuesto, se desvían un buen trecho del verdadero significado de la fecha, que poco o nada tiene que ver con aspectos materiales.


Pop/rock tip: Sir Elton John es indudablemente uno de los grandes genios de la música popular de la segunda mitad del siglo pasado. Su primer gran éxito, "Your Song", no puede faltar en ninguna antología de canciones románticas que se precie. Ojo, que a Elton no es fácil encasillarlo: también "le daba duro" al rock, algo de lo que dejan constancia clásicos como "Funeral for a friend/Loves lies bleeding" (a los más jóvenes, les recomiendo escuchar la versión en directo del tema que grabó Dream Theater para su disco "A Change of Seasons", de 1995).

David Crosby, Stephen Stills y Graham Nash, a quienes luego se unió Neil Young, formaron uno de los grupos más influyentes de la escena del folk rock norteamericano a partir de finales de los '60, tanto por su calidad interpretativa como por su activismo político. Valga la referencia a "Love the one you're with" para rememorar con simpatía los ideales hippies de aquella generación.

 

Publicado por Octavio Hernández | 8 comment(s)
Archivado en:

"Gimme back my bullets
Put 'em back where they belong..."
("Gimme back my bullets", Lynyrd Skynyrd, 1976)

Repasando los comentarios (algunos míos) a los tres posts sobre el uso de la sentencia lock publicados recientemente por mis PLAIN-hermanos Pablito, Unai y Rodrigo, encontré un fragmento de código que me ha dado la idea para éste, relacionado con la necesidad de utilizar patrones try-finally (o alguna de las sentencias que se apoyan en ellos, como using o lock) siempre que se soliciten recursos de cualquier naturaleza, para garantizar su devolución.

El fragmento de código en cuestión es similar a éste:

class LockDemo
{
    private static object locker = new object();
    public void MethodA()
    {
        System.Threading.Monitor.Enter(locker);
        // synchronized work
        System.Threading.Monitor.Exit(locker);
    }
}

¡Norrrrr!, Chiquitus dixit. Si por cierta razón quisiéramos utilizar explícitamente la clase Monitor en nuestro código, la manera correcta, que garantiza la liberación del bloqueo del objeto de sincronización incluso si se produce alguna excepción no gestionada durante el trabajo sincronizado, sería:

class LockDemo
{
    private static object locker = new object();
    public void MethodA()
    {
        System.Threading.Monitor.Enter(locker);
        try
        {
            // synchronized work
        }
        finally
        {
            System.Threading.Monitor.Exit(locker);
        }
    }
}

Si se revisa la especificación del lenguaje, se verá que ésa es exactamente la semántica de la sentencia lock:

class LockDemo
{
    private static object locker = new object();
    public void MethodA()
    {
        lock (locker)
        {
            // synchronized work
        }
    }
}

En mis cursos siempre insisto hasta el aburrimiento en la necesidad, de cara a una programación robusta, de que al programador se le meta en la sangre la obligación de devolver, ASAP (a la mayor brevedad posible) y no matter what (pase lo que pase), cualquier recurso que pida prestado a su entorno. Hacer otra cosa es simplemente escribir programas que van dejando (si se me perdona la expresión) una estela de mierdaproblemas detrás de sí.


Pop/rock tip: No es la primera vez que mencionamos a Lynyrd Skynyrd en este blog. "Gimme back my bullets" daba título a su cuarto álbum, salido en 1976, casi simultáneamente con el directo del que ya hemos hablado y un año antes del trágico accidente de aviación que le costó la vida a su líder, Ronnie Van Zant, y a dos miembros más de la banda.

 

Publicado por Octavio Hernández | 4 comment(s)
Archivado en: