Mostrando entradas con la etiqueta c#. Mostrar todas las entradas
Mostrando entradas con la etiqueta c#. Mostrar todas las entradas

martes, 16 de diciembre de 2008

Ja.NET SE: Java 5 JDK para .NET

IKVM, bridge entre Java y .NET del que ya hablé en su día, ya tiene rival. ¿Duro? Lo veremos, de momento sólo puedo decir que hoy me he topado con otro de estos famosos puentes que intentan de alguna manera enlazar las dos plataformas de desarrollo software más conocidas y utilizadas.

El proyecto en cuestión se denomina Ja.NET y deriva del proyecto Apache Harmony, proyecto que aboga desde hace tiempo por un Java SE totalmente opensource, en otra palabras, un Java SE no tan made in Sun Microsystems ;-). Los creadores de Ja.NET pretenden ofrecer una implementación opensource del entorno Java 5 SE JDK para .NET, incluyendo librerías, herramientas, y por supuesto, un entorno de ejecución basado en .NET, es decir, una especie de Java Virtual Machine "a lo .NET".

Aparentemente, este nuevo JDK, en vez de generar el famoso e interoperable Java Byte Code a ejecutar por las típicas JVMs, tiene toda la magia para poder compilar código Java a código CIL (antes conocido como MSIL), código que podría ser directamente invocado desde una aplicación C# por ejemplo. Parece que esta conversión utiliza Cecil, una potente librería de Mono para inspección y modificación de assemblies.

¿Qué os parece el remix? Yo mismo no soy muy partidario de estos bridges o pegamentos de segunda clase, sobre todo por el overhead que suponen en su mayoría. Ahora bien, hay casuísticas un tanto extrañas en las que estas utilidades pueden tener su hueco. Por ejemplo, cuando tenemos una lógica de negocio o ciertos algoritmos muy complejos implementados en Java desde hace un porrón de tiempo, puede pasar que al jefe de proyecto de turno, se le ocurra la brillante idea de desarrollar una aplicación .NET para darle a la aplicación una interfaz de usuario más atractiva para los usuarios. ¿A que suele pasar? Está claro que lo que vende es el mariconeo de pantalla ;-).

Pues bien, ahí es donde yo creo que pueden entrar este tipo de frameworks; sería cuestión de compilar el código Java con Ja.NET para generar código que pueda ser utilizado desde una aplicación desarrollada en C# ó VB.NET por ejemplo. La verdad es que el enfoque se me hace muy similar, por no decir igual, que el de IKVM.

A ver si saco algo de tiempo para hacer unas pequeñas pruebas comparativas entre IKVM y Ja.NET, y de paso monitorizo el avance de estos dos interesantes proyectos. Por el momento, IKVM Vs. Ja.NET, pronto en sus PCs de desarrollo ;-).

Vía: InfoQ

SaludoX.


lunes, 20 de octubre de 2008

El timeout del comando sí importa

Hoy retomo un tema relacionado con MySQL que la semana pasada no pude terminar por culpa de un error bastante serio de Google. No voy a hablar directamente de MySQL, pero sí voy a desahogarme con un problemilla (¡qué típico!) que he tenido a la hora de acceder a esta base de datos a través de programación. Sirva como adelanto comentar que este problemilla es extrapolable a todas las bases de datos del mercado; sin embargo, como las pruebas han sido contra MySQL, le daremos el dudoso honor de aparecer en mi post a ella ;-).

El caso es que la semana estuve midiendo tiempos y rendimiento de diferentes sentencias DML lanzadas contra MySQL. Más que nada, me interesaba analizar el comportamiento de los procedimientos almacenados o stored procedures que MySQL soporta a partir de la versión 5.0, frente a las clásicas sentencias en texto plano de select, insert, update y delete. Aunque existen herramientas tipo query analyzer que exprimen todo el jugo a cada consulta y miden tiempos y rendimiento de manera bastante precisa, me apetecía medir tiempos desde el mismísimo campo de batalla, desde la trinchera del programador, a pie de código. Inmejorable ocasión por tanto para probar MySQL Connector/NET 5.2 (última versión de este conector disponible a día de hoy) desde una aplicación de consola dummy programada en C#. Aparte de que quería probar este conector, tiene su lógica hacerlo de esta manera, ya que hoy en día toda aplicación que necesita acceder a base de datos utiliza conectores de diversos tipos dependiendo de la tecnología y lenguaje de programación que se esté utilizando.

Sin más preámbulos ni rollos macabeos, me centraré (por fin) en narrar lo que me pasó durante estas pruebas realizadas contra una base de datos MySQL remota, aunque dentro de las misma red que mi equipo de trabajo. Como siempre, todas estas pruebas y comparaciones suelen empezar suavecito, con sentencias select no demasiado complicadas, 1000 inserciones en una tabla, etc. Hasta aquí todo bien, tiempos parecidos, incluso ligeramente mejores para las queries en texto plano. Palabras mayores, paso a ejecutar un programita que realiza 100000 (cien mil) inserts en texto plano dentro de un bucle for en C#, es decir, ni más ni menos que 100000 llamadas a ExecuteNonQuery(). La ejecución tarda un rato, casi dos minutos, pero va bien, las filas son insertadas como Dios manda (¿Cómo manda Dios?).

Pasamos entonces a ver qué tal funciona lo mismo, pero haciendo una única llamada desde código al método ExecuteNonQuery(). ¿Cómo? Llamando (a gritos) a un stored procedure que realiza las mismas inserciones, aunque en un loop interno definido en el propio procedimiento almacenado, no a nivel de código cliente. ¡Vamos allá!

¡Pues va a ser que ha petado! A ver qué dice el error lanzado por el conector..."Fatal error encountered during command execution". Buff, ¡qué mal rollo Arroyo! Sinceramente, me he quedado igual o peor, no tengo ni idea de qué está pasando, y el error lanzado no es de gran ayuda, como ocurre desgraciadamente muchas veces.

Vuelvo a ejecutar varias veces lo mismo con idéntico resultado, hasta que me apiado y paulatinamente voy bajando el número de inserciones del procedimiento almacenado hasta llegar a un punto en que ¡funciona! ¿Tendrá MySQL un límite de memoria/hilos/procesos en los procedimientos almacenados? No creo..., entonces, ¿será cosa del conector? Mientras me hago esta última pregunta me quedo mirando fijamente la consola, concretamente mi atención se centra en el tiempo cronometrado (por mí) que se muestra tras el error, 30 segundos y pico. ¡Ajá! Ya caigo..., me suena que las sentencias SQL tienen un timeout, es más, me suena que ese timeout suele tener por defecto un valor de 30 segundos. Vamos a tirar de la ayuda, que para algo la suelen realizar...

Efectivamente, confirmado queda que el comando para atacar la base de datos tiene un timeout por defecto de 30 segundos, lo que implica que si el comando no termina, se dispara un error. Claro, ahora todo coincide ya que seguramente la ejecución del stored procedure dura más de 30 segundos, lanzándose la excepción nada aclarativa recibida. ¿Solución? Establecer un valor más alto para dicho timeout. Aunque no se recomienda tocar este parámetro ya que es difícil que la ejecución de una query o stored procedure dure más de 30 segundos (excepto en las monstruosas transacciones y procesos batch que realizan bancos y demás), esta vez vamos a añadir una simple línea de código C# asignando un valor entero muy alto al timeout del command, pa' cubrirnos las espaldas ;-).

Compilamos, y ¡allá vamos de nuevo!

¡Voilá! Como se puede apreciar en la imagen de arriba, las 100000 inserciones se han realizado perfectamente, en un tiempo ligeramente inferior a las 100000 inserciones realizadas "a pelo".

Como adelantaba al principio del post, aunque en este caso particular el ejemplo se ha desarrollado con el conector de .NET para MySQL, esto mismo sirve para otros conectores, tanto a MySQL, como a Oracle, SQL Server, Sybase, o el repositorio de datos que sea. De hecho, si no me equivoco, todos los conectores a base de datos vienen por defecto con un timeout por comando de 30 segundos, tiempo más que suficiente en el 99.99% de los casos, y si no anda Lonifasiko por ahí cerca con ganas de marcheta ;-).

Tened en cuenta por tanto que el timeout en los accessos a base de datos existe, y aunque rara vez se da, hay casos en los que se supera y es necesario reajustar su valor manualmente por código. Soy el primer timeout-breaker, o ¿tiene alguien alguna otra experiencia similar que contar con otro conector hacia MySQL o hacia otra base de datos? Seguro que sí...

SaludoX.


lunes, 22 de septiembre de 2008

CsharpRepl, shell interactivo de C#

Tras la dura resaca de mi primer cumpleaños (¡que joven que soy!), hoy lunes "de empanada monumental" toca hablar sobre las andanzas de l@s imparables chic@s de Mono, que como siempre, están que no paran. Una vez más me entero de una excelente utilidad/herramienta gracias a mi habitual lectura del blog más tirano de la blogosfera opensource .NET. Esta vez, el project leader Miguel de Icaza nos daba a conocer la utilidad CsharpRepl, que viene a ser una especie de shell interactivo de C#. En otras palabras, una parte del compilador de C# de Mono que nos permite evaluar expresiones y ejecutar sentencias contra el runtime de Mono a través de la línea de comandos.

Puede que esta utilidad no sorprenda a los habituales de ciertos lenguajes de scripting; ni tampoco a los "comodones" como yo que utilizamos Visual Studio como herramienta de desarrollo, ya que este entorno integra la siempre útil ventana de "Inmediatos", que viene a ser más o menos lo mismo que CsharpRepl. ¡Qué de alegrías nos ha dado esta dichosa ventanita y cuántas veces ha evitado que tengamos que recompilar nuestra aplicación! Aunque parezca increible, todavía hoy en día hay muchos programadores que desconocen las maravillas que encierra esta ventanita mágica que traga con (casi) todo. Es un "must-try" pero mucha gente no la conoce porque inexplicablemente viene oculta por defecto dentro de Visual Studio, ¡hay que activarla a mano! Manda huevos...

Bueno, volvamos al tema que nos ocupa, que no es otro que CSharpRepl, el shell que te evitará hacer debug 178 veces. Disponible ya en los nightly builds de Subversion a partir del día 1 de Septiembre, el comando csharp que habilita este shell vendrá ya integrado en la versión 2.2 de Mono. Aunque el equipo está abierto (como siempre) a todo tipo de sugerencias de funcionalidad a incorporar a la utilidad, de momento el shell publicado permite cargar assemblies, importar namespaces, evaluar expresiones más o menos complejas, utilizar LINQ a machete e incluso escribir pequeños programitas de varias líneas gracias a la edición multi-línea:

Admito que empezar a realizar pruebas con Mono sigue siendo una de mis asignaturas pendientes para la nueva temporada 2008/2009, pero seguro que con este tipo de utilidades y herramientas con las que nos deleita muy a menudo el equipo de Mono, mi pas(it)o al lado oscuro será algo más indoloro. Ya que estamos, para no olvidarme de mis promesas y objetivos de cara a la temporada 2008/2009, voy a empezar a utilizar CSharpRepl desde ya mismo:

csharp> var goals = new string[]{"write quick and better posts", "write posts frequently", "increase readers", "a more professional look & feel blog", "earn some money"};
csharp> goals.Add("test Mono");

Mono Team, thanks again for your time and effort.

SaludoX.


domingo, 23 de marzo de 2008

DOR: Debug Or Release

El mismo colega (¡suerte en tu nueva etapa campeón!) que sacaba a la luz las carencias del método String.Replace me ha vuelto a poner a prueba con otra duda existencial sobre el fascinante mundo de Microsoft .NET y Visual Studio. No sé cómo lo hace, pero al final siempre consigue que me ponga cabezón y me pique con estos "retos tecnológicos" que me plantea:

Colega: "Miguel, ¿cómo puedo saber, sin tener el código fuente, si un ensamblado .NET, bien sea un .exe o una .dll que me han pasado, está compilada en modo debug o release?"

Miguel (con cara de póker...): "Joder tío, es que te pasan unas cosas...me vienes con cada preguntita...en serio, acabas antes si escribes un libro tronco..."

Colega: "¡Ja, te he vuelto a pillar tío! No, en serio, tranqui, no te piques ni pierdas tiempo con ello, era por si te sonaba alguna forma rápida de poder saber eso..."

Como me jode no poder ayudar a un compañero con una duda que a priori parece tan sencilla y evidente. ¿Que no pierda tiempo, que no me pique? No sabes lo que estás diciendo chaval...acabas de herir mi orgullo informático hasta lo más profundo, ese orgullo friki con tintes de batalla y autosuperación que todo informático posee (aunque algunos no lo saquen a relucir). Y es que si no fuera por estas aventurillas y mini-retos, ¿qué sería de la triste vida de un informático? Vamos allá...

Mirando por Internet y todavía con el orgullo malherido, en seguida encuentro este post que explica de maravilla cómo diferenciar las versiones debug y release. Una vez más, se cumple el principio básico de todo error o duda informática: "Mira por Internet, seguro que antes que a ti le ha pasado a alguien...".

Como bien indican en ese útil post, para saber si una librería o ejecutable .NET (hablamos siempre de managed code) está compilado en modo debug o release, sólamente hace falta leer los atributos del ensamblado (librería o ejecutable) en cuestión. Fiándome 100% de lo que dicen, basta con mirar el valor del atributo IsJITTrackingEnabled; si está a true, la .DLL o el .EXE están compilados en modo debug; si está a false, se trata de una versión release.

Para leer los atributos de un ensamblado .NET (.NET assembly), tenemos varias posibilidades:
  • Utilizar alguna utilidad gratuita como Reflector for .NET. ¡Qué gran utilidad!
  • Complicarse la vida y hacerlo mediante código .NET, cargando dinámicamente la assembly en cuestión y analizando sus atributos "al vuelo".
Al no tener nada mejor que hacer en este frío y lluvioso Domingo de Pascua (¡qué triste!), y porque en el fondo soy un "batallador informático" (¿?), he cogido prestado parte del código expuesto en el post del amigo Jim, y me he currado una pequeña utilidad que a través de una interfaz gráfica muy sencilla nos dirá si un ensamblado .NET está en versión debug o release. Ésta es la apariencia inicial de la aplicación:


Si pulsamos el botón saldrá un cuadro de diálogo donde podremos seleccionar el ensamblado .NET que queremos chequear:

Y poco más...una vez seleccionado el ensamblado .NET, la utilidad nos mostrará de forma gráfica si se trata de una versión debug (como en la imagen) o release:


Indicar que la aplicación sólo funciona para ensamblados .NET, es decir, para managed code, y que tan sólo necesita tener instalado .NET Framework 2.0 en vuestra máquina (lo tendréis ya instalado...). Os dejo tanto el ejecutable, como el código fuente de la utilidad (proyecto de Visual Studio zipeado) en mi espacio de SkyDrive.

Para aquellos temerosos del malware creado por desconocidos como yo, deciros que la utilidad es totalmente inofensiva; no os va a formatear vuestro disco duro, ni va a recopilar las credenciales de vuestra cuenta de GMail; como mal mayor, la aplicación pegará un pete brutal y os dejará con la miel en los labios, sin saber si el ensamblado era debug o release; lo siguiente será cagarse en mí mil veces y escribir un comentario en el post diciendo que soy una paquete ;-). ¡Pues vale! ¡Qué le vamos a hacer! Se aceptan todo tipo de críticas y comentarios...es la dura vida del blogger informático ;-)

SaludoX.


jueves, 20 de diciembre de 2007

El algoritmo de la felicidad en pseudo C#

El "día L" está al caer. Sí, me refiero al sábado día 22 de Diciembre, el día de la lotería y de las ilusiones, digo pajas mentales. A continuación os presento mi particular método de comprobación (programado en pseudo C#) para ver si me ha tocado "El Gordo" y las consecuencias que este premio podría tener. De ilusiones se vive...allá va:

private void CheckGordo(int gordoNavidad)
{
if (Lonifasiko.Loteria.Decimos.Find(gordoNavidad) ||
Lonifasiko.Loteria.Participaciones.Find(gordoNavidad))
{
Console.WriteLine ("¡Toma esa! Me ha tocado el Gordo de Navidad")
Lonifasiko.Mood = Mood.IncrediblyHappy;
Lonifasiko.InviteFamily = Lonifasiko.InviteFriends = true;
Lonifasiko.Car = new Car("Subaru Impreza");
Lonifasiko.Houses[0].Hipoteca.Cancel();
Lonifasiko.Works[0].WorkMode = WorkMode.MoreRelaxed;
Lonifasiko.Blogs[0].DedicatedTime++;
Lonifasiko.AnnualJourneys++;
Lonifasiko.SomeCaprichos.Allowed = true;
Lonifasiko.LifeStyle = LifeStyle.SeeLifeWithOtherEyes;
}
else
{
Console.WriteLine ("¡Siga jugando! Con un poco de suerte alguna pedrea...")
Lonifasiko.Loteria.TryLoteriaNiño = true;
Lonifasiko.LifeStyle = LifeStyle.Current;
}
}

Será que soy un poco zoquete, pero no consigo tabular el código ni de coña...

Que la suerte os acompañe...

SaludoX.


lunes, 22 de octubre de 2007

Una carencia del método String.Replace del .NET Framework

El otro día me viene un colega del curro y me comenta: "Miguel, mi aplicación recibe un string cuyo contenido varía, y yo siempre tengo que reemplazar el carácter en la posición 1 (siempre en esa posición), por el carácter 'P'. ¿Cómo hago esto en C#?"

Casi antes de que acabe la pregunta, le corto y le comento super orgulloso de la muerte por mi rapidez de reacción y supuesto control de C#: "¡String.Replace tío!, de toda la vida..."

Me dice que ya lo ha mirado pero que no hay manera. "¿Que no qué...?". Como buen cabezón que soy, abro el Visual Studio y hago la prueba en cuestión:

string s = "ihj";
s = s.Replace(


Según abro el paréntesis y navego por las dos únicas definiciones que tiene String.Replace, mi cara de póker va en aumento. String.Replace permite únicamente reemplazar uno o varios caracteres por uno u otros caracteres, pero no hay manera de reemplazar un carácter en una determinada posición por otro carácter u otros. ¡Pues vaya!

Aunque no me mola demasiado, saco el librillo de "viejo zorro" y le propongo un par de alternativas que funcionan que te pasas. ¡Tachán!

// Alternativa1
s = s.Remove(1, 1).Insert(1, "P");

// Alternativa2
char[] array = s.ToCharArray();
array[1] = 'P';
s = new string(array);

Just in case (y porque la curiosidad me come por dentro), pongo un post en Internet, donde la discusión se anima en seguida, y donde me intentan convencer a toda costa con diferentes razonamientos y alternativas de programación:

// Alternativa3
StringBuilder sb = new StringBuilder("ihj");
sb[1] = 'P';


Muy bien, está bien saber que hay más "viejos zorros" en el mundo de la programación, pero las explicaciones no me convencen en absoluto, y menos las soluciones o workarounds (algunas bastante "chapus"; otras "requete-enrevesadas") que algunos plantean. Por ello, me uno a la causa de mi colega y propongo a MS un feature request con el que añadan una sobrecarga al método String.Replace del .NET Framework. Tan sencillo como esto:

String Replace(int indexToChange, string newCharactersToReplace);

Con lo que hacer s = s.Replace(1, "P") se convertiría en un auténtico y cómodo placer.

SaludoX.


lunes, 24 de septiembre de 2007

Tuneando el "botón Inicio" de Windows

Que levante la mano el programador que NO haya acudido alguna vez en busca de alguna librería, control o code snippet a The Code Project. Bien, es lo que me esperaba: no veo ninguna mano levantada, con lo que doy por hecho que es un sitio de sobra conocido por tod@s. Los que no hayan levantado la mano por vergüenza, no pasa nada, que entren al sitio y echen un vistazo.

Para gente que quiere estar al día, particularmente recomiendo suscribirse al newsletter diario, donde te enterarás de infinidad de noticias de las que nunca te hubieras enterado en ningún otro sitio. Aparte de estas daily hot news, mensualmente mandan un mail muy completo con resúmenes de nuevos artículos publicados, etc.

A lo que voy: estaba leyendo este último mail cuando me llamó la atención este curioso artículo que hablaba sobre cómo cambiar mediante programación el texto del botón "Inicio" de Windows. Al igual que otras muchas opciones del interfaz de Windows, daba por hecho que se trataba de editar "con precaución" alguna entrada del registro de Windows, es decir, regedit y a tirar millas. Pero claro, mucho mejor si me lo dan en forma de ejecutable gracioso ;-)

Total, que me bajo la demo del artículo, descomprimo y ejecuto el archivo start.exe para que aparezca una pantalla como ésta:

En mi caso, introduzco el saludo vasco por excelencia (¡Aupa!), y pulso "Rename". La graciosa aplicación me avisa que el cambio lo veré después de reiniciar la máquina. Reinicio y voilá:

Espero que en los comentarios del post, cada uno comente con qué texto ha tuneado su botón. Seguro que salen cosas graciosas.

SaludoX.