lunes, 30 de junio de 2008

Primer proyecto finalizado!

Ya está la Versión 1.0 del Formateador de código fuente que vamos a usar tanto en el motor de blog que estamos desarrollando junto con THE ASP-BERRIES como para publicar los ejemplos acá en el blog.
La idea surgió de la incomodidad que presenta formatear el código fuente para que se vea como corresponde (como en el editor de Visual Studio 2008).
Formatea código C#, JavaScript, VisualBasic y ASPX/HTML/XML (también soporta JavaScript entre <script> y </script> y C# entre <% y %> en el ASPX).
El código fuente (incluye una página de prueba) y la versión 1.0 están en CodePlex, en el proyecto Source Code Formatter.
Enjoy!!

domingo, 29 de junio de 2008

Tratamiento de Cadenas en C#

El lenguaje C#, al ser un derivado del lenguaje C, tiene ciertos caracteres que tienen un significado particular, y al ser incluidos en una cadena de texto deben ir precedidos por el caracter de escape ("\").
Por ejemplo: para escribir "C:\" en una cadena deberemos escribir "C:\\".
Pero, qué pasa si queremos escribir una cadena como la cadena de conexión del ejemplo de Conexión a la base de Datos de Diego?
Puede resultar muy engorroso tener que escribir "\\" por cada subdirectorio. Lo que además resulta complicado de leer. (Ni hablar si se está escribiendo una expresión regular!!!)
Para esto existe una solución!!!
Se debe anteponer a la cadena el símbolo "@", para que la cadena sea tomada tal como está (internamente el compilador tendrá que poner todos los caracteres de escape que necesite).
Ejemplo:
La cadena de conexion original tenía lo siguiente:

string strConexion = "Data Source=.\\SQLEXPRESS;AttachDbFilename=E:\\sql\\MSSQL.1\\MSSQL\\Data\\Celula.mdf;Inte...";

Para que quede más legible la podemos reescribir de la siguiente manera:

string strConexion = @"Data Source=.\SQLEXPRESS;AttachDbFilename=E:\sql\MSSQL.1\MSSQL\Data\Celula.mdf;Inte...";

miércoles, 25 de junio de 2008

2 x 1

En estos poco más de dos meses que llevamos juntos logramos que se una gente a nuestra célula. Tanto es así que llegó un momento que había gente que estaba colaborando pero no podía inscribirse como un miembro más ya que habíamos alcanzado el límite de 10 personas.
Viendo esta situación es que la semana pasada decidimos dividirnos en dos células. Ambas trabajando, por ahora, sobre el mismo proyecto.
El nombre de la nueva célula es THE ASP-BERRIES, su líder es Diego y el blog está en http://aspberries.blogspot.com/.
En nombre de la gente que quedó de este lado, les deseo muchos éxitos!!!
Cuenten con todos nosotros para lo que necesiten.

jueves, 19 de junio de 2008

Memoria y Performance

C# es el lenguaje de programación que actualmente se utiliza en el desarrollo de aplicaciones ASP.NET, una de sus principales ventajas es que cuenta con "recolector de basura" o Garbage Collector.
Esto es un proceso que revisa la memoria buscando aquellas asignaciones que los programadores ya no utilizamos.
Por ejemplo: si en alguna parte de la aplicación tenemos algo como

1: public void AlgunMetodo()
2: {
3: AlgunaClase miObjeto = new AlgunaClase();
4: // hacemos lo que tenemos que hacer con el objeto
5: ...
6: }


Cuando la ejecución del metodo finaliza, la memoria utilizada por "miObjeto" pasa a ser inaccesible dado que no tenemos la referencia a esa zona de memoria. En algún momento el Garbage Collector encontrará esa zona de memoria y se dará cuenta que ya no se puede acceder desde la aplicación y la devolvera al sistema de manera que se pueda volver a utilizar.

Antes de la existencia del Garbage Collector, los programadores teníamos que tener mucho cuidado y liberar la memoria antes de perder la referencia correspondiente.

El problema es que el Garbage Collector comienza a funcionar cuando se ha consumido el 90% de la memoria !!!
Esto significa que en ese punto ya estamos hasta las manos, y como si fuera poco se agrega un proceso al pool de ejecución que baja la performance de forma notable.

La solución a esta situación es implementar la interfaz IDisposable.

Esta interfaz obliga a las clases que la implementan a codificar el método Dispose(), en el ejemplo anterior si en la definición de AlgunaClase se implementa la interfaz, podríamos hacer lo siguiente:



1: public void AlgunMetodo()
2: {
3: AlgunaClase miObjeto = new AlgunaClase();
4: // hacemos lo que tenemos que hacer con el objeto
5: miObjeto.Dispose();
6: }


Con eso ya solucionamos el problema, dado que el metodo Dispose() devuelve la memoria ocupada sin tener que llegar al 90%.
El problema que tenemos ahora es que debemos acordarnos de invocar al metodo para todos los objetos que utilizamos, es para volverse locos.

Entonces veamos cómo hay que implementar IDispose para una clase:


1: public class AlgunaClase : IDisposable
2: {
3: // Este es el constructor de la clase
4: public AlgunaClase()
5: {
6: // se crea un arreglo de 100 elementos
7: // hay que considerar que _Datos es una
8: // referencia a un arreglo creado en el
9: // momento en que se crea una instancia
10: // de esta clase
11: _Datos = new OtraClase[100];
12: }
13: private OtraClase[] _Datos;
14:
15: // Este es el destructor o finalize de
16: // la clase, se invoca automáticamente
17: // cuando un objeto es destruido.
18: // Esto ocurre cuando se sale del ámbito
19: // de existencia del objeto.
20: public ~AlgunaClase()
21: {
22: // Invoca a Dispose, la sobrecarga que
23: // utiliza argumento para liberar los
24: // recursos propios de la instancia
25: // en este ejemplo es _Datos pero no
26: // libera la memoria asignada al arreglo
27: Dispose(false);
28: }
29:
30: // Aquí va lo que esta clase necesita
31: ...
32:
33: // Este es el método que debe implmentarse
34: // para cumplir con la interfaz
35: public void Dispose()
36: {
37: // En este caso se invoca el metodo con
38: // un parametro que obliga a liberar los
39: // recursos consumidos internamente en la
40: // instancia.
41: Dispose(true);
42: // Con esto se le avisa al Garbage Collector
43: // que no debe hacer nada con esta instancia
44: GC.SuppressFinalize(this);
45: }
46:
47: // Este campo se utiliza para indicar que una
48: // instancia de esta clase ya ejecutó el Dispose
49: private bool _IsDisposed = false;
50:
51: // Este metodo es el que realmente libera la
52: // memoria del objeto cuando el argumento es
53: // verdadero, se liberan los recursos consumidos
54: // dentro del objeto, como ser otro objeto creado
55: // con el operador new.
56: // cuando el argumento es falso, solamente se
57: // liberan recursos no administrados.
58: protected virtual void Dispose(bool disposing)
59: {
60: if (!_IsDisposed)
61: {
62: if (disposing)
63: {
64: // Aquí se trabaja con los recursos administrados
65: // se debe liberar cada uno de los elementos de la
66: // otra clase, se asume que OtraClase también
67: // implementa un metodo Dispose.
68: if (_Datos != null)
69: {
70: foreach(OtraClase o in _Datos)
71: {
72: o.Dispose();
73: }
74: // la referencia _Datos se libera cuando la
75: // instancia es destruida.
76: }
77: }
78: // Aquí se trabaja con los recursos no administrados
79: // como ser una handler a un archivo abierto.
80: }
81: // Finalmente indicamos que ya se hizo el Dispose.
82: this._IsDisposed = true;
83: }
84: }


Observesé que cuando una instancia de AlgunaClase se destruye no se libera la memoria asignada en el arreglo de objetos de OtraClase, esto se puede solucionar invocando al metodo protegido con un parámetro true.

Lo que ocurre es que el diseñador de clases debe analizar mediante algún diagrama de secuencias cómo se utilizan las instancias. En este caso, el destructor está pensado para liberar solo los campos internos de la clase y no los recursos creados internamente; esto es así porque se piensa utilizar las instancias en un bloque using, como se muestra a continuación:

1: using(AlgunaClase miObjeto = new AlgunaClase())
2: {
3: // Hacer lo que se tenga que hacer
4: }


Cuando se codifica de este modo, el compilador genera el siguiente código:

1: AlgunaClase miObjeto = new AlgunaClase();
2: try
3: {
4: // Hacer lo que se tenga que hacer
5: }
6: finally
7: {
8: if (miObjeto != null)
9: miObjeto.Dispose();
10: }


Con lo que se asegura la liberación de los recursos creados internamente en la instancia dado que el método público Dispose invoca al metodo protegido con el argumento true.

Por supuesto es mucho más cómodo utilizar la sentencia using, dejando que el compilador haga su trabajo.

Finalmente me gustaría comentar que tampoco es cuestión de poner código como este para todas las clases que una aplicación necesita, siempre hace falta un mínimo análisis de que es lo que se va a hacer y cómo se hara.

La información sobre todo estó la encontré en MSDN, incluso pueden ver un ejemplo para clases derivadas.

viernes, 13 de junio de 2008

Silverlight 2 Beta 2

Ya está disponible la Beta 2 de Silverlight 2.
Los links para la descarga de las herramientas y documentación en el blog de Ivana.
A probarlo!!!

viernes, 6 de junio de 2008

Cadenas en .NET


Las cadenas del tipo System.String en .NET son inmutables. Esto quiere decir que cualquier cambio a una cadena provoca que el entorno de ejecución cree una nueva cadena y abandone la vieja. Esto es invisible, y muchos programadores se podrán asombrar al aprender que el siguiente código almacena cuatro nuevas cadenas en la memoria:


string s;

s = "Uno"; // "Uno"
s += " Dos"; // "Uno Dos"
s += " Tres"; // "Uno Dos Tres"
s += " Cuatro"; // "Uno Dos Tres Cuatro"
Console.WriteLine(s);

Sólo la última cadena tiene una referencia, las demás serán desechadas en el proceso de recolección de basura. Evitar este tipo de cadenas temporales ayuda a evitar recolección de basura innecesaria, lo que mejora la performance. Existen varias maneras de evitar las cadenas temporales:

  • Usar los métodos Concat, Join, o Format de la clase String para unir múltiples elementos en una sola declaración.

  • Usar la clase StringBuilder para crear cadenas dinámicas (mutables).


El uso de la clase StringBuilder es la solución más flexible. El siguiente código muesta el uso de la clase StringBuilder:


System.Text.StringBuilder sb = new System.Text.StringBuilder(30);
sb.Append("Uno"); // Construir la cadena
sb.Append(" Dos");
sb.Append(" Tres");
sb.Append(" Cuatro");
string s = sb.ToString(); // Copiar el resultado en la cadena
Console.WriteLine(s);

lunes, 2 de junio de 2008

Prototipo de Administración

Ya tenemos el prototipo que nos permitirá explorar las alternativas de la administración del motor de blog.

Contamos con un editor de publicaciones el TinyMCE, que por ahora está con todas las opciones; hay que revisar eso y definir que opciones quedan, probablemente haga falta dos o tres variantes.
En la página oficial de TinyMCE se puede hallar un proyecto que implementa una interfaz o control que permite utilizar el editor, por ahora me pareció más cómodo utilizarlo directamente sin embargo ya estoy viendo que al incorporar más de un textarea en la misma página se duplicará todo el código en javascritp.

Hay un prototipo de clase base para la mayoría de los objetos (post, páginas, comentarios), se debe revisar los estandares de WeblogAPI y RSS para ver que más hace falta.

En el prototipo se está almacenando las páginas en App_Data/Pages en formato XML, incorpore una clase utilitaria que implementa extensiones vean este post sobre ese tema. Desde luego la persistencia se hará en una base de datos, lo que pasa es que esto es más rapido para probar la interfáz y lógica.
Cuidado, si van a probar el sitio con IIS deben asignar derechos de escritura en esa carpeta.


Bueno ahora hay que armar un prototipo de como funcionaría el motor de blog para los lectores.