2007

Controlar errores no controlados con C#

Algo que me gusta de PHP es su control de errores, ya que a pesar de no tener un tipo de error común, sino que tenemos que luchar contra errores y excepciones, dispone de dos funciones para controlaras como set_error_handler y set_exception_handler.

Cuando desarrollo aplicaciones en C# echaba de menos estos algún método similar para capturar excepciones, probé varias cosas lógicas, entre ellas antes de hacer nuestro Application.Run, englobarlo todo dentro de un try y catch al siguiente estilo:

try {
  Application.Run(new Formulario());
} catch {
  Application.Run(new Formulario());
}

Esto controlaba cualquier excepción, pero me cerraba la aplicación, una opción era volver a hacer un Application.run en el catch. Si fuera una calculadora hubiera valido, pero cuando se trata de una aplicación grande, no es una solución. Tampoco podemos dejarla al aire, puesto que cuando se lance una excepción, se cerrará la aplicación.

Buscando, buscando, encontré un evento llamado Application.ThreadException, que controlara todas aquellas excepciones que se produzcan dentro de Application.Run. Controlando este evento, no tendremos que catchear todo nuestro código, sino que definiremos una ventanita que recogerá la excepción y avisara al usuario de que se ha producido un error. Dentro de esta ventana, dependiendo de cuanto queramos trabajárnosla, podremos dar opción al usuario para enviar la traza de la excepción para que el equipo de desarrolladores, pueda reparar el error para futuras versiones o actualizaciones y así poco a poco, generar una aplicación grande desde el principio y robusta poco a poco si se van controlando aquellos errores que no son los más comunes.

A continuación os dejo el código de como controlar cualquier excepción desde el principio.

using System
using System.Windows.Forms;
using System.Threading;namespace myespacio {

  internal sealed class MiPrograma {

    [STAThread]
    private static void Main(string[] args) {
      Application.ThreadException +=
      new ThreadExceptionEventHandler
        (MiPrograma.excepcion);

      Application.Run(new Formulario());
    }

    public static void excepcion(object sender,
          ThreadExceptionEventArgs excepcion) {
      MessageBox.Show("Se ha producido un error");
    }
  }
}

Ubuntu 7.04 Feisty Fawn con MP3 y Amarok

En los últimos años, mi único roce con Linux/Unix ha sido RedHat 9 como escritorio, y Fedora, Debian, FreeBSD y Solaris como servidor. Además de que la lista de distribuciones que he tocado de Linux/Unix es pequeña, realmente nunca me había planteado como hasta hace poco pasar a usarla en mi casa no como servidor de experimentos.

Mi primer roce de escritorio al estilo Windows (ya que RedHat 9 hace ya muchos años) fue PCLinux OS, que tuve que sustituir por mi actual Ubuntu 7.04 por razones de ejecución de algunas aplicaciones. Pero descubrí algunas aplicaciones en esta distribución que me gustaron mas que las que tiene Ubuntu, como es Amarok como reproductor de sonido.

Me instalo desde Synaptic Amarok e intento reproducir un par de canciones en mp3, resulta que me da un error. Investigando por internet encuentro que el error se debe a un problema de licencias entre Ubuntu y mp3.

La solución al problema de reproducción de mp3 en Ubuntu 7.04, es bien sencillo. Tenemos que buscar la librería libxine-extracodecs en Synaptic y la instalamos. Una vez instalada, ya podemos reproducir música en formato mp3 con Amarok y supongo, aunque no lo he probado, con el resto de reproductores.

amarok2-7screenie

Counter Strike Source en Linux con Wine

Bueno, hace poco renové desde 0 un ordenador que tenía por ahí. La verdad es que lo mismo me hubiera dado si lo hubiera comprado todo, porque una cosa llevo a la otra, y al final lo único que conservo de este viejo ordenador es la carcasa, grabadores de CD y DVD, así como el teclado y el ratón.

El caso es que decidí utilizar Linux en esta pedazo de máquina que me había montado. En el portátil y el otro ordenador lo tenía con Windows XP y Windows Vista no termina de convencerme, por lo que me he decidido por meterle un Linux.

Aunque me gusta trabajar con el ordenador, sigue viviendo dentro de mi el espíritu de ese niño jugón, así que después de configurar un poco el ordenador con los drivers propietarios de NVidia, que por cierto en Ubuntu 7.04 es un click de ratón gracias a su gestor de controladores restringidos, me puse a saco con Wine a ver si conseguía jugar al Counter Strike Source con Steam, a los que tantos vicios me he hechado en Windows.

Lo primero que hice fue buscar por internet, a ver como lo hacia la gente y lo que la gente hacia era sencillísimo, lo que me hizo pensar que realmente no lo hacían, sino que era el cancer de los Blogs, «el copy/paste». Cuando realmente intente lo que iban exponiendo blog por blog, me di cuenta que realmente era un copy/paste, ya que en todos ponía lo mismo y era super sencillo, solo le faltaba a alguno decir que Ubuntu ya venía con el Counter instalado. Los que realmente si merecían la pena eran para el Counter Strike 1.6, con el que no tenía ningún problema. Así que tocaba buscar y buscar por internet alguna solución.

Para el que le pueda servir de ayuda indicare paso a paso lo que hice para poder jugar al Counter Strike Source con Wine.

En primer lugar, me baje la última versión de Wine disponible, la 0.9.45 desde la página web del proyecto Wine, y compile los sources. Con esto conseguí mas bien poco, ya que si era capaz de arrancar Steam, pero no el Counter Strike Source. Fue un tiempo muy bonito desperdiciado, ya que el tiempo que perdí en compilar y en instalar dependencias de fuentes, pudo ser como 2 o 3 días.

Pantallazo de Counter Strike Source en Linux

Visto que la última versión de Wine no me iba a ayudar, o yo no sabia decirle que me ayudara, hice un «make uninstall» y la borre. Así que busque por el Sysnaptic para instalar la versión de Wine de los repositorios de Ubuntu que era la versión 0.9.33. Con esta versión conseguí un gran paso, ya que ahora si que podía arrancar el Counter Strike, pero tenia que elegir, entre poder jugar sin sonido, o tener sonido pero no poder jugar. Aquí fue cuando me puse a buscar por un loco por internet y encontré dos posibles soluciones, una pagina web que ofrece los paquetes .deb de la última versión de Wine y el Cedega, un fork de Wine que esta orientado a juegos.

Lo primero que hice fue tirarle a Cedega 6, que tenia hasta un panel para instalar y jugar y la verdad tenia muy buena pinta. Porque no me quede con Cedega, pues porque por un lado es de pago (que si merece la pena me da igual pagar) y por otro lado porque no fui capaz de correr el Counter Strike.

Ya solo me quedaba una ultima opción antes de rendirme, era esa página donde se encontraban los últimos paquetes .deb de Wine, así que instale la versión 0.9.45 con un solo click de ratón y arranque mi Steam y posteriormente el Counter Strike Source, y ¡¡¡por fin!!! pude jugar con sonido, conectarme a partidas a internet. Como nota decir que si instalais Steam y no os aparecen las letras, deberéis copiar la fuente Tahoma a la carpeta Windows/fonts del directorio de wine.

Para hacer una comparativa del Counter Strike Source en Windows XP y en Linux con Wine 0.9.45, puedo deciros que en Windows las texturas tienen mayor calidad, en Linux no me permite cambiar las opciones de vídeo, en Linux es infinitamente más rápido en cuanto a conexiones, cambio de servidor, etc. y por último en Linux no tiene reflejos de agua o cristales y tampoco tiene luces dinámicas como la linterna y similares. Así que la conclusión es que como en Windows no va en ningún lado, pero que en Wine 0.9.45 va bastante bien.

También os comento un único problema, con Beryl el Counter Strike Source me daba problemas, así que lo cambie por Compiz para que no me diera problemas por ejemplo al cambiar de cara del cubo.

Pantallazo de Counter Strike Source en Linux con Compiz

No se puede viajar al pasado con Java

Por esas casualidades de la vida y probando un sistema de aplicación de Java que usaba la hora del servidor, hicimos pruebas cambiando la hora del sistema para probar que todo funcionaba correctamente. Mientras modificábamos la hora para comprobar el buen funcionamiento, encontrábamos algún que otro bug, que corregíamos recompilando sobre la marcha.

Después de 30 minutos de constantes pruebas, y cuando nos disponíamos a realizar la compilación definitiva para realizar un pequeño parche en nuestra aplicación, nos encontramos con un problema, ¡No podemos compilar! Tenemos un problema, Java nos dice al intentar compilar que tenemos una versión más reciente ya compilada. Con las prisas y las pruebas y arreglos sobre la marcha, compilamos sin querer en el año 2008 y claro, ahora en el año 2007, Java no nos permite compilar ya que una compilación posterior ya se encuentra en el sistema.

La solución, aunque un poco drástica, se nos ocurrió en cuanto se nos paso la cara de tontos, ya que realizamos un backup y borramos todas las clases compiladas para volver a generarlas.

Es un poco curioso que Java no nos permita compilar, o mejor dicho, recompilar una clase que ya se compilo en el futuro. Si alguien os dice que sois vosotros mismos que viene del futuro para daros una versión superior de alguna clase vuestra, no se la toméis, porque no os dejara compilarla.

Controlar eventos de Windows en C#

En .Net hay una clase que dispone de una serie de eventos propios del sistema operativo, que nos permite manejar o ser advertidos de ciertas modificaciones en el mismo, como podría ser el caso de modificaciones de hora, pantalla, etc. De esta forma podremos aplicarlas sobre la aplicación y que esta no haga extraños cuando se modifica algo en el sistema.

La clase encargada de eventualizar ciertas acciones del sistema operativo se encuentra dentro del espacio de nombres Microsoft.Win32 y se trata de la clase abstracta y no heredable SystemEvents. Esta clase provee de los diferentes tipos de eventos que listo a continuación con una breve descripción.

  • DisplaySettingsChanged: se produce cuando el usuario cambia la configuración de pantalla.
  • DisplaySettingsChanging: se produce cuando la configuración de pantalla esta cambiando.
  • EventsThreadShutdown: se produce antes de que finalice el subproceso que escucha los subprocesos del sistema.
  • InstalledFontsChanged: se produce cuando el usuario agrega o quita fuentes del sistema.
  • LowMemory: se produce cuando el sistema se queda sin memoria RAM disponible.
  • PaletteChanged: se produce cuando el usuario cambia a una aplicación que utiliza una paleta diferente.
  • PowerModeChanged: se produce cuando el usuario suspende o reanuda el sistema.
  • SessionEnded: se produce cuando el usuario cierra sesión o apaga el sistema.
  • SessionEnding: se produce cuando el usuario intenta cerrar sesión o apagar el sistema.
  • SessionSwitch: se produce cuando se cambia la sesión entre usuarios.
  • TimeChanged: se produce cuando se cambia la hora del sistema.
  • TimerElapsed: se produce cuando ha transcurrido el intervalo de un temporizador de Windows.
  • UserPreferenceChanged: se produce cuando cambian las preferencias del usuario.
  • UserPreferenceChanging: se produce cuando van a cambiar las preferencias del usuario.

De esta pequeña lista no he probado todas, pero si algunas con un correcto funcionamiento. Hay muchos eventos que pueden ser utilizados como el hecho de la memoria baja para lanzar el recolector de basura o el control de cierre de sistema para guardar los datos en memoria en un archivo.

Para utilizarlas se utilizaría el siguiente código:
[code language=»csharp»] using Microsoft.Win32;

//… LINEAS INTERMEDIAS

SystemEvents.TimeChanged += new System.EventHandler(this.message);

//… LINEAS INTERMEDIAS

public void message(object sender, EventArgs e) {
MessageBox.Show(«Han cambiado la hora del sistema.»);
}
[/code]

Diferencias entre preg_match y ereg

Voy a explicar la diferencia entre estas dos funciones propias de PHP para evaluar y extraer información sobre cadenas mediante el uso de expresiones regulares o patrones.

Aparentemente estas 2 funciones son aparentemente iguales. Las diferencias entre ellas son mínimas, como por ejemplo que en preg_match es obligatorio establecer unas barras que delimitan el patrón, o que esta función devuelve un entero (int) de 0-n, en función de las coincidencias encontradas, mientras que ereg devuelve un booleano en función de si ha encontrado o no coincidencias.

Entonces. ¿Dónde radica la diferencia entre preg_match y ereg? Pues la principal diferencia ya que ambos también devuelven un array con las coincidencias por referencia, es la potencia. La función preg_match es muy potente y muy útil al igual que ereg. Generalmente se suele utilizar preg_match para extraer información de un texto y la función ereg para evaluar si un texto cumple un patrón o no, como es el caso de un email [a-zA-Z0-9]{1,}@[a-zA-Z0-9]{1,}.[a-zA-Z]{2,3}. El problema viene cuando realizamos un patrón relativamente complejo sobre un texto extenso, es ahí cuando vemos la verdadera diferencia de potencia entre preg_match y ereg. Si comparamos vemos que preg_match podría llegar a tardar 60 segundos en analizarlo (hablo por propia experiencia) mientras que el mismo patrón evaluado con ereg, tardaría unos 5 o 6 segundos.

En conclusión podríamos decir que preg_match es una función ideal para analizar y realizar patrones sobre textos relativamente pequeños, tal como el contenido de una pagina web por ejemplo, y ereg es para evaluar patrones rápidos como palabras o emails y cuando el patrón a evaluar es muy muy grande.

ACTUALIZACIÓN

Este artículo lo escribí hace casi 10 años. En ese momento era todo correcto. Con el tiempo la función ereg, heredada de PERL fue marcada como deprecated y de hecho ya no se encuentra en PHP7. Aunque ereg seguía siendo más rápida que preg_match, a esta última función le han añadido más versatilidad.

También comentar que la cadena de validación del email es un ejemplo, antiguo e incompleto.

Conectar a una url, webservice o REST en C#

Hoy en día se necesita conectar con páginas web, bien sea para extraer información de una página o para conectar contra un WebService. DotNet o .Net, nos provee de una serie de herramientas para la conexión contra WebServices, pero hay casos excepcionales, en los que necesitaremos conectarnos de una manera más arcaica y tradicional, al estilo de la librería cURL por ejemplo. En este caso mostrare un ejemplo de como conectarnos a una url de un WebService ficticio y como recoger su contenido para luego ser tratado. En primer lugar crearemos un String donde poner la url de la conexión. Seguidamente conectaremos utilizando los objetos HttpWebRequest y HttpWebResponse y generaremos un StreamReader con la respuesta. El código quedaría así:

[code language=»csharp»] String baseUri = «http://rutaalwebserice»;
HttpWebRequest connection = (HttpWebRequest)HttpWebRequest.Create(baseUri);
connection.Method = «GET»;
HttpWebResponse response = (HttpWebResponse)connection.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
[/code]

Ya tenemos nuestra variable sr (StreamReader) para poder utilizarla para trabajar con el supuesto XML o HTML devuelto. Es importante apuntar, que para utilizar estas librerías, necesitamos incluir los siguientes nombres de espacio:

[code language=»csharp»] using System.Web;
using System.Net;
using System.IO;
using System.Text;
[/code]
Scroll al inicio