Cartuja .NET working

En Sevilla, a estos maravillosos 40 grados, nos vamos a juntar unos cuantos en el primer evento del grupo de usuarios de .NET de Sevilla, Cartuja.NET, de este año.

Así que si te gustan las tecnologías, especialmente las de Microsoft, trabajas con ellas, o te gustaría hacerlo pero no sabes cómo, nos vamos a reunir para hablar sobre MS, las tecnologías que están o van salir, conocernos y hacer networking.
¿Quieres saber más? Vente el Dia: 4 de Julio
Lugar: En la Calle Presidente Cárdenas, 41013 Sevilla (SE)   Hora:  8 de la tarde (con la fresquita)

No hace falta que os regitréis ni nada.

Nos tomaremos unas cervezas en el bar Qcross mientras charlamos sobre todo esto y más.

Updated:

Y si queréis estar al tanto de lo que se cuece en CartujaDotNet, noticias, eventos, o contactar con otros participantes, podéis uniros al grupo CartujaDotNet en Facebook, LinkedIn, o seguirlo a través de Twitter.

Más artículos hablando sobre este tema:

Os esperamos!

Segundo camino para alcanzar el Nirvana del Garbage Colector y cuál elegir

En este segundo post sobre la serie de optimizaciones en juegos en el que vamos a ver la segunda forma de optimizar el proceso de recolección de basura, evitando caídas de rendimiento en nuestros juegos.

Latencia adecuada.

El tiempo que consume el proceso de recolección de basura es directamente proporcional a lo complejo que sea nuestro heap. Si el heap está vacío, el recolector no tendrá nada que hacer.

Fijaos que hemos dicho «lo complejo que sea nuestro heap». La complejidad del heap es una combinación del número de objetos vivos y el número de referencias a objetos que tengamos. En realidad no importa nada el tamaño en bytes que los objetos del heap tengan: lo que realmente importa es el número total de objetos (ya que el recolector debe examinar cada uno de ellos) y el número de referencias a objetos (el recolector debe seguir cada referencia para ver a qué está apuntando cada una).

Cuando medimos la complejidad del heap, un array de 100.000 enteros es poco costosa. Aunque ocupe mucha memoria, el recolector de basura sólo tiene que examinar el objeto una vez, y no tiene que mirar dentro.

100.000 arrays, cada una con un entero dentro será más costoso, ya que el recolector tiene más objetos que examinar.

Un array de 100.000 referencias a objetos es también más costoso, ya que aunque el array es sólo un objeto, el recolector tiene que recorrer todas las referencias para ver si cada objeto que contenga el array tiene que seguir vivo. Aunque el array sólo contenga nulls, el recolector los tiene que recorrer todos para asegurarse.

Aquí tenéis unos consejos para reducir la complejidad del heap:

  • Es mejor algunos objetos grandes antes que muchos objetos pequeños.
  • Mejor tener en el heap  tipos por valor que  referencias.
  • Cuantas menos referencias a objetos mejor.
  • Los arrays de tipos por valor son tus amigos!
  • Considera reemplazar referencias a objetos por manejadores enteros, es decir, en lugar de guardar una referencia la nave que creó la bala, podrías guardar el «fui creado por la nave 23» como un entero directamente.
  • Es prefeible un T[] o List<T> antes que un LinkedList<T> o un Dictionary<K,V>

Los discípulos del camino de la latencia no se preocupan de reservar memoria durante el juego. Pueden llamar a news, causar boxings, y usar delegados anónimos y métodos generadores. No les importa que pase el recolector de basura, ya que su heap es tan simple que el proceso termina muy rápido.

¿Cuál de los dos caminos elijo?

Podemos obtener un mejor rendimiento evitando las reservas de memoria, de manera que el recolector nunca pasará. Esto funciona sin importar lo complejo que sea nuestro heap.

También obtendremos un mejor rendimiento manteniendo nuestro heap simple, el recolector tardará muy rápidamente. Esto funciona aunque reservemos memoria durante el juego.

¡¡Lo que no podemos hacer es mejorar el rendimiento mezclando ambas soluciones!! Se consigue muy poco reservando memoria sólo para la mitad de memoria necesaria y tener un heap de complejidad media. Eso producirá un juego con un tamaño medio cada pocos segundos.

Si tu objetivo es evitar la recolección de basura, debes elegir sólo uno de los caminos y seguirlos hasta el final.

Reinicia tu cabeza

Los programadores nuevos en el mundo de evitar la recolección de basura piensan que pueden mejorar el rendimiento llamando a GC.Collect en momentos específicos.

Casi siempre se equivocan. Forzar la recolección de basura es una receta para confundir al recolector y dañar su rendimiento.

Pero…

En Xbox, el .NET Compact Framework realiza una recolección de basura cada vez que se ha reservado un megabyte.

Supongamos que estamos optimizando nuestro juego para evitar reservar de memoria. Después de un estudio cuidadoso con el CLR Profiler hemos conseguido reducir a 50 bytes por frame las reservas de memoria que hacemos, pero no conseguimos reducirlo más, no hay manera.

Además, digamos que nuestro juego se ejecuta a 60 frames por segundo, y que un nivel típico tarda 2 minutos en completarse. Al final del nivel tendremos reservados sólo 352k, no es suficiente para que el recolector se ejecute. En realidad, nuestro juego puede estar hasta 5 minutos sin tener que recolectar nada, el único momento en el que el jugador notará que está pasando el recolector de basura es si él mismo se dedica a recorrer el universo «perdiendo el tiempo».

Suena razonable no? Seguramente podríamos vivir con ello.

Pero…

Estaremos reservando mucha memoria mientras se carga el nivel, y esto causará muchas recolecciones. En realidad no es un problema: no está mal que el recolector pase en este momento, ya que a la pantalla de carga no le importa el framerate.

Pero ¿qué pasa si durante la carga se reserva algo menos de un número de megabytes, por ejemplo 24,452k? Después de la última recolección en el mega 23, esta operación de carga reserva muy poco como para lanzar otra recolección, pero lo suficiente como para dejarnos sin espacio. Ahora nuestro juego sólo puede reservar 124k antes de lanzar otra recolección, así que el jugador notará esto sólo cuando lleve 42 segundos en el nivel.

La solución es llamar a GC.Collect al final de cada método de carga. Esto limpiará cualquier recolección que hiciese falta, reseteando el reloj para que tarde más en pasar el recolector.

Juan María Laó Ramos.

Artículo original.

Windows Azure Media Services

Hace un mes que se anunció la salida de Windows Azure Media Services.

Es el servicio en la nube que nos permite construir y publicar soluciones multi-media a nuestros clientes. Ofrece un montón de servicios listos para codificar, almacenar, proteger y lanzar por streaming (tanto live como bajo demanda) de video. También integra y expone servicios de nuestros partners – permitiendo una pila de funcionalidad increíble.

Podéis usar Windows Azure Media Services para entregar soluciones a cualquier dispositivo o cliente – como HTML5, Silverlight, Flash, Windows 8, iPads, iPhones, Android, Xbox, y Windows Phone. Windows Azure Services soporta una gran variedad de formatos de streaming – como Smooth Streaming, HTTP Live Streaming (HLS), y Flash Media Streaming.

Uno de los aspectos que hacen único a Windows Azure Media Services es que todas sus características están expuestas usando una API REST HTTP. Esto es así tanto para los servicios multimedia, como para los servicios de nuestros partners. Esto hace que sea muy fácil automatizar workflows multimedia e integrar los servicios en nuestras aplicaciones. Como el resto de Windows Azure, sólo hay que pagar por los servicios de Windows Azure Media Services que usemos – haciendo que el coste sea muy interesante.

Windows Azure Media Services

Windows Azure Media Services usa el mismo backend que se usa para ofrecer eventos de deportes en vivo – como los juegos Olímpicos de Invierno de 2010, el Mundial de Fútbol 2010, los Campeonatos de Wimbledon 2011 y la SuperBowl 2012. Con Windows Azure Media Services podremos montar y automatizar soluciones en la nube que sean capaces de ofrecer soluciones a una gran audiencia.

Aprende más

Hemos usado Windows Azure Media Services en el 2012 National Association of Broadcasters (NAB) Show, los asistentes pudieron hablar con el equipo y ver demos en directo.

También podéis visitar windowsazure.com media para ver las características que ofrece, y pasaros por los recursos para desarrolladores de windowsazure.com para a ver cómo podemos usarlo. También podéis registraros para una cuenta de prueba enviando un email a mediaservices@microsoft.com (junto con los detalles del escenario para el que lo queréis usar).

Estamos deseando ver las cosas que sois capaces de hacer.

Scott.

Traducido por: Juan María Laó Ramos.

Artículo original.

Primer camino para alcanzar el Nirvana del Garbage Colector

Para ponernos en contexto y verlo más claro debemos saber que lo que vamos a ver es realmente importante en el mundo de los videojuegos ya que en este mundo el consumo de memoria y de recursos es algo crucial y hay que optimizarlos al máximo. En este sentido el proceso de recolección de basura es algo importantísimo ya que consume recursos del sistema y si se ejecuta en mitad del juego se puede producir una bajada de rendimiento importante.

En este primer post de la serie vamos a ver una de las formas de evitarlo.

Este es el post original de Shawn Hargreaves:

En este post vimos cómo saber si el recolector de basura de nuestra Xbox está tardando mucho. Vimos que el tiempo que tarda el recolector de basura es el resultado del producto del número de veces que se recolecta por la latencia misma de la recolección.

Esto nos hace pensar en dos formas de mejorar el rendimiento del proceso de recolección de basura. Podemos reducir el número de recolecciones, o podemos reducir la latencia del proceso de recolección. Con que consigamos reducir uno de esos valores se notará una mejora bastante notable en el rendimiento total.

En este post vamos a ver el primer caso:

Elegir una frecuencia de recolección adecuada

La frecuencia con la que se produce la recolección de basura es directamente proporcional al número de veces que reservamos memoria. Si nunca reservamos memoria, el proceso nunca se lanzará.

Para reducir el número de recolecciones, debemos reservar memoria para aquello que vamos a necesitar mientras cargamos los niveles, y evitar reservas de memoria en el tiempo de juego, evitando así que el recolector de basura entre en acción en mitad del juego.

Hay varias formas para evitar la reserva de memoria:

No reserves memoria (jah!)

Es simple, no hagas news de tipos por referencia. Está bien cuando lo hacemos con tipos por valor como Matrix, Vector3, Color y demás.

Cada vez que queramos hacer un new de un tipo por referencia, debemos usar un pool de objetos para reusar sus referencias. Los ejemplos de Particle y Audio 3D de creators.xna.com usan esta técnica, y SwampThingTom escribió sobre un pool genérico y reusable.

No uses clases que reserven memoria por sí mismas.

Cuando añadimos datos a una colección como un List<T> o un Dictionary<K,V>, se reserva memoria cuando se quieren ampliar. Podemos evitarlo usando el constructor existente en el que se indica el tamaño específico de la colección. Usando este constructor hacemos que se reserve la memoria necesaria para toda la colección haciendo que esta no tenga que ampliar ni disminuir la memoria que necesita.

Ten cuidado cuando formatees cadenas. Es difícil manipular cadenas en .NET sin causar reservas de memoria.

Evita que el CLR reserve memoria.

El CLR reserva memoria cuando ocurre el boxing. ¡Evítalos como si de una plaga se tratase! El boxing puede ocurrir por muchas razones, algunas son obvias, otras no tanto, veamos cuándo ocurre el boxing.:

  • Si asignamos un tipo por valor a una variable Object.
  • Si guardamos tipos por valor en una colección no genérica.
  • Si accedemos a tipos por valor a través de una interfaz.
  • Si usamos un enumerado como clave de un diccionario, las operaciones internas del diccionario generan boxings. Podemos evitarlo usando claves enteras (de tipo int), y hacer casting a los valores de nuestro enumerado antes de añadirlas al diccionario.

No dejes que el compilador de C# reserve memoria.

Puedes ser realmente tricky usar delegados (especialmente los que están definidos «inline») sin hacer que el compilador reserve memoria. Esto es todo un mundo por sí solo, pero en caso de duda evita el uso de delegados o eventos

Los yield hacen que el compilador reserve siempre memoria.

Los foreach pueden reservar memoria sin cuidado. Pero ojo, esto no significa que tengamos que evitarlos. Suele ser la forma más rápida de recorrer una colección.  Aprended las reglas para usarlos de manera adecuada

Todo lo que no reserve memoria está bien.

A los discípulos del camino de la frecuencia se les permite tener estructuras de datos complejos. Pueden reservar cientos de miles de objetos mientras su juego carga, llenar el heap con una malla de objetos referenciados entre si. Siempre que no reserven nada después de que termine de cargar, el recolector de basura nunca se ejecutará, así que no hay problema ninguno en mantener en memoria objetos complejos.

Resumen

Hemos visto una forma de hacer que el recolector de basura no se ejecute mientras se está jugando al juego: evitando hacer reservas de memoria durante el juego, en vez de eso las hacemos en el proceso de carga y se mantiene todo en memoria.

En el próximo post veremos la segunda opción: Elegir la latencia adecuada.

Juan María Laó Ramos.

Post original.

La "locura" de las optimizaciones en los juegos.

¿A quien no le preocupa que su código no sea óptimo? Eso de «funcionar funciona … pero tarda mucho» no es escusa para no preocuparse por optimizar las partes optimizables. Una de las mejores formas de evitarse problemas desagradables cuando el sistema está «terminado» es interiorizar los conceptos y aplicarlos en la práctica de manera casi automática.

Para ponernos en contexto y verlo más claro debemos saber que lo que vamos a ver es realmente importante en el mundo de los videojuegos ya que en este mundo el consumo de memoria y de recursos es algo crucial y hay que optimizarlos al máximo. En este sentido el proceso de recolección de basura es algo importantísimo ya que consume recursos del sistema y si se ejecuta en mitad del juego se puede producir una bajada de rendimiento importante.

Estos conceptos no son sencillos, ya que involucran «gran cantidad» de detalles que se suelen pasar por alto.

En un afán de mejorar y compartir lo aprendido vamos a ver en detalle un par de posts de  Shawn Hargreaves que he encontrado y que publicaré en varios posts para no saturar y podamos interiorizarlos mejor.

Espero que os sirva.

Juan María Laó Ramos

¿Veremos en The Windows Phone Developer Conference a WP Apollo?

Dentro de unos meses se cumplen dos años de la salida de Windows Phone 7 y un año de la de  Mango. Como no deja de ser una ciencia, la estadística nos dice que en Octubre estará disponible Windows Phone 8 Apollo.

Entre los días 22 y 24 de Octubre de 2012 también está programado el evento “The Windows Phone Developer Conference”   que en WPCentral  anuncian como el primer ciclo de conferencias de Windows Phone que no está patrocinado por Microsoft.

WPDevcon

En el programa del evento podemos ver la gran cantidad de sesiones sobre WP7. Sin embargo, en la noticia de WPCentral destacan que el gran artista invitado será Apollo, nombre en clave que los de Redmon han dado a Windows Phone 8. En WPCentral destacan que habrá una sesión específica para aprender todo lo que traerá Apollo, como resoluciones de pantalla, los cambios que habrá en el Marketplace,  las características que tendrá el nuevo emulador y se verá cómo migrar las aplicaciones de Mango a Apollo.

Todo un caramelo para desarrolladores, sin embargo si nos vamos a la web del evento y vemos el pdf con el programa no se hace referencia a Apollo en ninguna parte.  Lo que me ha llamado la atención es que en los comentarios de la noticia se han fijado en la fecha de creación y modificación del pdf. Así que parece que han eliminado las referencias a Apollo del documento.

¿Una estrategia de marketing para conseguir más asistentes? Es posible, pero sin duda que por esas fechas ya se tendrán más detalles sobre la nueva versión de Windows Phone y seguramente ese evento sea un lugar privilegiado para enterarnos de cómo adaptar las aplicaciones existentes a la nueva versión del sistema operativo.

Más tiempo para Cell·APP Awards

Las plegarias han sido oídas y  hemos ampliado el plazo para presentar juegos y aplicaciones a Cell·APP Awards:

Cell·App Awards

Desarrolla tu app usando CELL·SDK. Debes rellenar este formulario para participar y enviarnos el formulario de suscripción.

  • Fin de Inscripción: 31/05/2012
  • Último día para enviarnos tu app: 15/06/2012
  • Periodo de votaciones Online: Empezará una vez envíes tu app y nosotros la subamos. Este periodo acabará el 26 de Junio
  • El Jurado valorará las apps más votadas a partir del 28 de Junio.
  • La entrega de premios será el 29 de Junio.

Todavía no tienes Cell·SDK?! O_o

Pues descárgalo aquí.

CodeFluent Entities. Nunca el DDD fué tan fácil

Vamos a ver en este post es un producto que he encontrado y parece muy prometedor. CodeFluent Entities es una herramienta de modelado que nos permite generar y mantener actualizadas todas las layers y capas de nuestra aplicación. Asegurando el conjunto de buenas prácticas arquitecturales en nuestros sistemas desde su nacimiento. Esto es, han creado una herramienta para aplicar Domain Driven Development sin que apenas nos demos cuenta.

La he estado probando un tiempo y la verdad me ha dejado sorprendido, pensé en un momento que iba a ser un ORM más, pero luego descubrí el modelador de objetos de negocio, seguido de la generación de servicios RESTful, la sencillez de enlazar el modelo de negocio con las interfaces de usuario ASP.NET Web Forms, WPF y Windows Forms (están trabajando en los conectores para ASP.NET MVC, Silverlight). Continúa leyendo CodeFluent Entities. Nunca el DDD fué tan fácil

Cell·SDK y el emulador de Android

Hace unas semanas se publicó una actualización del emulador de Android que muchos estábamos esperando.

Entre otras cosas, la característica fundamental, y una de las más esperadas, es que esta versión del emulador por fin soporta la aceleración de GPU, necesaria para ejecutar aplicaciones que necesitan OPEN GL 2.0. Continúa leyendo Cell·SDK y el emulador de Android

Push Notifications en Cell·SDK

La semana pasada publicamos Cell·SDK 1.2 con un montón de nuevas características y algunas correcciones que hacen del desarrollo multiplataforma en iOS, Android y Windows Phone aún más sencillo.

En el post de hoy vamos a ver cómo enlazar lo que tenemos en el tutorial de Push notifications para Windows Phone y lo que podemos encontrar en la web de Microsoft sobre cómo mandar notificaciones a nuestros dispositivos.

Con el mismo código fuente que tenemos disponible en Github para la aplicación de ejemplo en el  dispositivo nos va a valer para este ejemplo.

Tenemos que tener en cuenta que debemos programarnos una pequeña aplicación/servicio para poder enviar notificaciones al servicio de notificaciones de Microsoft. Tal y como vemos en el diagrama y documentación de Microsoft:

Arquitectura Push

Nosotros tenemos que implementarnos el “Cloud Service” así que vamos a ver un ejemplo de cómo hacerlo según se indica aquí. De este último enlace sólo nos interesa la parte de “Sending a Toast Notification

Vamos a crear un proyecto de ASP.NET vacío y vamos a incluir cuatro controles TextBox y un botón para enviar la notifiación:

Página de envío

Ahora vamos a darle código al evento clic del botón:

protected void SendToast_Click(object sender, EventArgs e)
 {
 try
 {
 // Get the URI that the Microsoft Push Notification Service returns to the push client when creating a notification channel.
 // Normally, a web service would listen for URIs coming from the web client and maintain a list of URIs to send
 // notifications out to.
 string subscriptionUri = TextBoxUri.Text.ToString();

HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

// Create an HTTPWebRequest that posts the toast notification to the Microsoft Push Notification Service.
 // HTTP POST is the only method allowed to send the notification.
 sendNotificationRequest.Method = "POST";

// The optional custom header X-MessageID uniquely identifies a notification message.
 // If it is present, the same value is returned in the notification response. It must be a string that contains a UUID.
 // sendNotificationRequest.Headers.Add("X-MessageID", "");

// Create the toast message.
 string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
 "" +
 "" +
 "" + TextBoxTitle.Text.ToString() + "" +
 "" + TextBoxSubTitle.Text.ToString() + "" +

" " +
 "";

// Set the notification payload to send.
 byte[] notificationMessage = Encoding.Default.GetBytes(toastMessage);

// Set the web request content length.
 sendNotificationRequest.ContentLength = notificationMessage.Length;
 sendNotificationRequest.ContentType = "text/xml";
 sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
 sendNotificationRequest.Headers.Add("X-NotificationClass", "2");

using (Stream requestStream = sendNotificationRequest.GetRequestStream())
 {
 requestStream.Write(notificationMessage, 0, notificationMessage.Length);
 }

// Send the notification and get the response.
 HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
 string notificationStatus = response.Headers["X-NotificationStatus"];
 string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
 string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

// Display the response from the Microsoft Push Notification Service.
 // Normally, error handling code would be here. In the real world, because data connections are not always available,
 // notifications may need to be throttled back if the device cannot be reached.
 TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
 }
 catch (Exception ex)
 {
 TextBoxResponse.Text = "Exception caught sending update: " + ex.ToString();
 }

Este código puede estar tanto en una aplicación web, una aplicación de Windows forms, un servicio de Azure, etc…

Tan sólo tenéis que montarlo, desplegar la aplicación de ejemplo de github en el dispositivo ó en el emulador y copiar el Channel ID que saldrá en la ventana de Output de Visual Studio:

Channell ID en Visual Studio

Este código lo introducimos en la página web que hemos creado en el textbox primero y recibiremos en el dispositivo o emulador una notifiación Toast:

Toast Notification

Hay tres tipos de notificaciones para Windows Phone que podemos enviar:

  • Toast: Con documentación y ejemplos aquí
  • Tile: Con documentación y ejemplos aquí.
  • Raw: Con documentación y ejemplos aquí.

Os recomiendo que probéis a enviar otro tipo de notificaciones, en este ejemplo hemos usado el ejemplo de envío de notificaciones Toast.

Para ver el código fuente de la aplicación y cómo es la API Unificada para Android, iOS y Windows Phone de Cell·SDK no tenéis más que pasaros por aquí

Espero que os sirva.

Juan María Laó Ramos.