Design a site like this with WordPress.com
Get started

[Evento CartujaDotNet] Wave Engine

Wave EngineImagina que quieres hacer un juego, pero sólo quieres programarlo una vez y desplegarlo en la mayoría de plataformas posibles.

Deja de soñar y aprende a usar Wave Engine y podrás desplegar tus juegos en iOS, Android, Windows 8 y Windows Phone.

Los grandes Marcos Ligthyear y David Woody nos enseñarán todo lo necesario (y quizás algo más … ) para empezar a sacarle partido a Wave.

¿Dónde y cuando?

En el Cloud Pointing de Sevilla.

c Biología, 12, Edificio Vilamar 2, 3ª Planta
Parque Empresarial Nuevo Torneo
41015 Sevilla

El Jueves 23 de Mayo de 19:30 a 21:30.

Aquí tenéis juegos reales hechos con Wave Engine. Y estas son  unas cuantas demos tecnológicas.

¿Te lo vas a perder? Pues regístrate aquí

Microsoft Sync Framework 2.1 (COM Error 80040154 Class not registered)

He tenido que trabajar en un proyecto para sincronizar tanto bases de datos como blobs con Azure , Microsoft Sync Framework y Worker Roles.

Nota: Ibon Landa nos explica qué es un worker role de Azure aquí.

La cosa es que una vez instalado Microsoft Sync Framework y empezar a trabajar con él, estaba obteniendo una excepción que no entendía muy bien:

{“Retrieving the COM class factory for component with CLSID {EC413D66-6221-4EBB-AC55-4900FB321011} failed due to the following error: 80040154 Class not registered (Exception from HRESULT:

0x80040154 (REGDB_E_CLASSNOTREG)).”}

La máquina en la que suelo trabajar es una máquina x64, con el sistema operativo también en x64.

Tras un tiempo buscando por google pude llegar a la conclusión que no estaba encontrando el componente de Sync Framework. Tras comprobar que estaba todo instalado no conseguía averiguar cuál era el problema.

Ya desesperado me dio por pulsar en la segunda página de resultados de google y ahí estaba: Sync Framework 2.1 Com Error

La cosa es que como tenía un proyecto de test para probar las clases que iba creando, resulta que Visual Studio se ejecuta siempre en modo x86, y como los test se lanzan desde Visual Studio, no estaba encontrando las librerías correspondientes.

La solución

Instalar los componentes x86 de Sync Framework y problema resuelto.

Espero que sirva.

Juan María Laó Ramos

HttpAntiForgeryException en ASP.NET MVC

Hola a todos, gracias a Jose María Aguilar hoy he resuelto un pequeño problema con ASP.NET MVC de esos de los que te pegas dos días loco.

La cosa se puede reproducir muy fácilmente creando un nuevo proyecto MVC tal cual nos lo genera Visual Studio 2012:

        MVC Default Project         

Si la ejecutamos directamente  nos aparecerá la web por defecto totalmente funcionando. Ahora, vamos a registrar un nuevo usuario, y nos mantendremos logados.

Para reproducir el error que me ha vuelto loco sólo tenemos que deslogarnos, hacer clic en login y logarnos. Una vez logamos le damos al botón del navegador para que vaya a la página anterior, y veremos que se mantiene el nombre de nuestro usuario:User Logged

Y la gracia está en que si escribimos nuestro password y nos logamos obtenemos un bonito error:

Server Error in ‘/’ Application.


The provided anti-forgery token was meant for user “”, but the current user is “juanma”.

             Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.Mvc.HttpAntiForgeryException: The provided anti-forgery token was meant for user “”, but the current user is “juanma”.
Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[HttpAntiForgeryException (0x80004005): The provided anti-forgery token was meant for user "", but the current user is "juanma".]
   System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) +234369
   System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext) +71
   System.Web.Helpers.AntiForgery.Validate() +80
   System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext) +22
   System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +96
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +446
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +382
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71
   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929            

 Simplemente precioso.

Es un problema de la caché,  y es que el forgery-token se guarda información relativa a la sesión que hemos iniciado con el servidor, entre ellas el usuario logado. Al ser una petición GET el navegador intenta obtener ese token de la caché, pero el servidor se da cuenta de que ese token ha sido cargado de la caché del navegador y no ha sido generada en la petición actual, por lo que, para evitar ataques de Cross-Site Request Forgery, nuestro servidor (que es muy listo) dice: eh!, ¿a donde te crees que vas?

La solución para que el navegador no nos cargue ese token (y otras cosas) en las peticiones GET que hagamos cuando queremos logarnos es indicarlo en nuestro método de login. En un proyecto MVC4 por defecto, ese método está en la clase AccountController.cs

 [AllowAnonymous]
 public ActionResult Login(string returnUrl)
 {
    ViewBag.ReturnUrl = returnUrl;
    return View();
 }

¿Cómo se lo indicamos?, añadiendo el atributo OutputCache de la siguiente manera:

 [AllowAnonymous]
 [OutputCache(NoStore = true, Duration = 0)]
 public ActionResult Login(string returnUrl)
 {
    ViewBag.ReturnUrl = returnUrl;
    return View();
 }

Si recompilamos y ejecutamos repitiendo el proceso de logarnos, navegar a la página anterior con el botón del navegador y haciendo clic en Login, ya no nos aparece el nombre de nuestro usuario anterior, sino que aparece vacío y podemos logarnos sin ningún problema y sin excepciones

Espero que os haya gustado y de nuevo tengo que darle las gracias a Jose María Aguilar por su ayuda 🙂

El foreach puede causar problemas de memoria

Después de tener algo de tiempo he ido a mi lista de cosas por leer y me quedado a cuadros cuando lo he leído.

http://blogs.msdn.com/b/etayrien/archive/2007/03/17/foreach-garbage-and-the-clr-profiler.aspx

Sí es un enlace del 2007, lo sé, imaginaos la de cosas que tengo en esa lista :P.

En resumen, imaginemos este código:


class Program
{
    class GameEntity
    {
        public void Update()
        {
        }
    }

<pre><code>static GameEntity[] entities = new GameEntity[100];
static Program()
{
    for (int i = 0; i &amp;lt; entities.Length; i++)
    {
        entities[i] = new GameEntity();
    }
}

static void Main(string[] args)
{
    byte[] byteArray = new byte[1];
    for (int i = 0; i &amp;lt; entities.Length; i++)
    {
        entities[i].Update();
    }
}
</code></pre>

}

En el post original, después de pasar el CLR Profiler no se hace reserva de memoria para un enumerador para poder recorrer la colección, algo lógico. Después, para ver la diferencia con el foreach sustituye el código del for por este otro:

static void Main(string[] args)
{
   byte[] byteArray = new byte[1];
   foreach (GameEntity e in entities)
   {
      e.Update();
   }
}

En el caso del foreach se reserva memoria para un enumerador necesario para recorrer el foreach.

Y todo va perfecto, sin embargo, hay un escenario en el que se pueden producir fugas de memoria:

const int NumEntities = 100;

static List list = new List();
static Program()
{
   for (int i = 0; i < NumEntities; i++)
   {
         list.Add(new GameEntity());
     }
}
static void Main(string[] args)
 {
     UpdateIEnumerable(list);
 }
private static void UpdateIEnumerable(IEnumerable enumerable)
 {
     foreach (GameEntity e in enumerable)
     {
         e.Update();
     }
 }

En este caso sí se producen fugas de memoria. Y es que aunque estemos haciendo un foreach en una lista, cuando se le hace un casting a una interfaz, al tipo valor del enumerador se le hace un box, y se coloca en el heap.

La conclusión:

  • Cuando hacemos un foreach sobre un Collection<T> se reserva memoria para un enumerador.
  • Cuando hacemos un foreach sobre la mayoría de las colecciones, como arrays, listas, colas, listas enlazadas y otras:
    • Si se usan explícitamente, NO se reserva memoria para un enumerador.
    • Si se usan a través de interfaces, se reserva memoria para un enumerador.

Así que si el consumo de memoria es algo crítico en vuestra aplicación o juego , nunca, nunca, uséis interfaces para recorrer una colección.

 

[Update: Gracias a Bernardo por el comentario]

El problema aparece cuando el “foreach” recorre la colección como si fuera un “IEnumerable”. En este caso se utiliza la implementación explícita de “GetEnumerator()” y se realiza “boxing” del “struct” para devolver un tipo “IEnumerator”.

El “boxing” es una operación costosa y puede llegar a consumir mucha memoria.

P.D: el método “GetEnumerator()” de  “Collection” no devuelve un “struct”. Es de las pocas colecciones que son una excepción.

Espero que os haya gustado tanto como a mi. 🙂

Juan María Laó Ramos.

Están locos estos de Redmond

Vaya sorpresa que me acabo de llevar, y es que en Redmond hacen las cosas a lo grande. Si ayer anunciaron el nuevo servicio Outlook.com, hoy, hace apenas unos minutos han anunciado:

  • Windows Store: Han abierto la Windows Store para poder empezar a mandar nuestras apps para Windows 8.
  • Windows 8: Han publicado la última release RTM de Windows 8.
  • Visual Studio 2012 y .NET 4.5: Ya han llegado a las últimas builds de Visual Studio y lo lanzarán en Septiembre, pero el 15 de agosto estará disponible para los suscriptores de MSDN.

¡Se nota que estamos en verano y la cosa está que arde!

Megathon Windows 8, ¿te lo vas a perder?

Hackathon Windows 8

¿Megathon, qué es eso?

Fácil, si has asistido a algún Hackathon de Windows Phone que se estuvieron haciendo el año pasado por toda la geografía española en diferentes fechas, esta vez es ¡en un montón de ciudades en la misma fecha todos a la vez!

La idea surgió por twitter en un momento de locura sana de Jose Bonnin (@wasat)

Durante los días 7, 8 y 9 de Septiembre tendremos que crear una aplicación Metro para Windows 8. Durante esos días de poco sueño se darán charlas sobre cómo programar apps Metro para Windows 8 usando C#/XAML o HTML5/JavaScript/CSS3 y contaremos con mentores que nos ayudarán a completar su App.

Yo ya estoy apuntado, ¿te lo vas a perder?

http://megathonwindows8.azurewebsites.net/

Windows Azure y Office 365

La última Beta de Microsoft Office 365 y SharePoint han introducido un montón de mejoras, entre ellas un montón para desarrolladores. Ahora podremos extender SharePoint creando aplicaciones web con ASP.NET (tanto con Web Forms como con MVC), incluso podemos crear nuevos workflows usando el nuevo Workflow Framework en .NET4.5

Aún mejor, las apps web y workflow que creemos para extender SharePoint se pueden hostear en Windows Azure. Ya estamos ofreciendo soporte entre Office 365 y Windows Azure que hace super fácil desplegar estas soluciones.

Soporte de Office 365 y Windows Azure

 Desarrollando sitios web en Windows Azure integrados con Office 365

El mes pasado publicamos una actualización de Windows Azure. Uno de los nuevos servicios que incluimos en esa actualización fue la característica que llamamos Windows Azure Web Sites – que nos permitía rápida y fácilmente desplegar aplicaciones web en Windows Azure. Con el nuevo Office, SharePoint Server 2013 y Office 365 Preview de la semana pasada, ya podemos crear aplicaciones para Office y SharePoint y hostearlas en Windows Azure.

Podemos usar cualquier versión de ASP.NET (tanto Web Forms, MVC y Web Pages) para crear aplicaciones para SharePoint, y autenticarnos e integrarlas con Office 365 usando OAuth 2 y Windows Azure Active Directory. Esto nos permite crear/leer/actualizar de manera segura los datos almacenados en SharePoint, e integrarlos con los repositorios de rich data y de documentos en Office 365.

Además de permitir hostear estas aplicaciones en Windows Azure, la nueva versión de Office 365 y SharePoint también nos permiten subir aplicaciones web personalizadas a Office 365. Los usuarios finales podrán navegar entre esas aplicaciones en el nuevo Store de Office y SharePoint disponible con Office 365 e instalarlas en nuestras soluciones de SharePoint. Esto hará que Office 365 despliegue una copya de la aplicación como un sitio web de Windows Azure, y Office 365 la administrará para el cliente final. Esto ofrece una forma convincente para que los desarrolladores creen y distribuyan aplicaciones web personalizadas que extiendan SharePoint, y opcionalmente monetizarlas a través del Store.

Podéis aprender más sobre cómo crear estas soluciones y cómo el nuevo modelo de nube para Office y SharePoint aquí, y más sobre cómo crear aplicaciones para SharePoint aquí.

Desarrollando Workflows de Windows Azure integrados en Office 365

La nueva versión de SharePoint permite ejecutar Workflows de .NET 4.5 personalizados en respuesta a acciones de SharePoint (por ejemplo, un usuario sube un documento, o modifica elementos en la lista de SharePoint). Los Workflows de .NET 4.5 permiten workflows de SharePoint más:

  • expresivos: introduciendo etapas y bucles que aprovechan los diagramas de flujo de workflows de .NET 4.5
  • connectados: soportando las llamadas REST y OData a servicios web, y a endpoints de ASP.NET  Web API
  • ilimitados: ejecutando los workflows fuera de los servidores SharePoint en un host robusto, escalable y consistent

Con la preview de Office 365, podemos autorizar y subir workflow a nuestras soluciones de SharePoint. Office 365 usa un nuevo servicio de Windows Azure Workflow para ejectuarlos en Windows Azure. Los desarrolladore sy los clientes de Office 365 no tiene que instalar nada en sus Windows Azure para permitir esto (ni siquiera tener una cuenta de Windows Azure) – ya que la integración es automática entre Office 365 y Windows Azure.

Podemos autorizar estos workflows usando el propio diseñador de Office SharePoint o desde Visual Studio 2012. En el Office SharePoint Designer, podemos crear workflows .NET 4.5 tanto desde el diseñador visual:

Office Share Point Designer

O desde la vista de texto (similar al mago de reglas de Outlook):

Vista de texto de Workflow SharePoint

Los desarrolladores podemos usar el diseñador de Workflow y las herramientas para Office de Visual Studio 2012:

Diseñador Workflow Visual Studio 2012

El soporte de workflow ofrece una forma fácil de personalizar el comportamiento de las acciones de SharePoint, y ejecuta su lógica en Windows Azure. Todo esto se puede hacer sin que el desarrollador tenga que personalizar SharePoint ni desplegar las apps a mano (ni siquiera hace falta logarse con una cuenta de Windows Azure – Office 365 lo hace automáticamente). Como los workflows pueden realizar ahora llamadas asíncronas a través de REST o de OData, también es muy fácil autorizar a los workflows para que llamen a una funcionalidad personalizada o a servicios que se estén ejecutando en Windows Azure (por ejemplo: un servicio escrito con ASP.NET Web API) e integrar los datos o la lógica en nuestra solución de SharePoint.

Resumen

Las actualizaciones de este verano de Windows Azure y Office 365 traen un montón de nuevas características. Podemos usar cada uno de los servicios de manera independiente, o usarlos juntos para desarrollar soluciones más competitivas. Visitad el Office Developer Center para aprender más y empezar hoy.

Espero que sirva.

Scott.

Traducido por: Juan María Laó Ramos.

Artículo original.

 

 

Entity Framework y Open Source

El Entity Framework ha avanzado mucho en los últimos años. Hace poco más de un año que se publicó EF 4.1, que introdujo la nueva API DbContext y el soporte Code First. A principios de este año publicamos EF4.3, que incluyó Code First Migration que permite a los programadores evolucionar un esquema de base de datos en un código optimizado. Y ya estamos al final y a punto de lanzar la release EF 5, que añade soporte para enumeradores, tipos de datos spatia, soporte para funciones table-valued, mejoras de rendimiento y mejoras en las herramientas de Visual Studio.

Una de las cosas que ha hecho el equipo entre las versiones 4 y 5 ha sido la de involucrar a la comunidad desde muy al principio y a medida que tomábamos decisiones de diseño y pedíamos feedback. Para la versión 6 buscamos llevar esto al siguiente nivel optando por un modelo abierto de desarrollo.

El código fuente del Entity Framework se ha publicado bajo una licencia open source (Apache 2.0), y el repositorio está hosteado en CodePlex (usando Git) para incrementar la transparencia del desarrollo. Esto permitirá que cualquiera pueda ofrecer feedback en los checkings de código, correcciones de bugs, desarrollo de nuevas características y construir y testear el producto usando siempre la última versión del código y los tests. Las contribuciones de la comunidad también son bienvenidas, así que podéis convertir al Entity Framework en un producto mucho mejor. Podéis encontrar todos los detalles en el sitio de CodePlex del Entity Framework.

El pasado Diciembre las SDKs de Windows Azure adoptó este modelo abierto de desarrollo, y en marzo vimos que ASP.NET MVC, ASP.NET Web API y ASP .NET Razor también pasaron a este modelo. Estos productos han mostrado que este modelo abierto es una forma genial de conseguir un gran feedback de la comunidad, y al final del día tenemos mejores productos.

Mismo soporte, mismos desarrolladores, más inversión.

Muy importante – Microsoft continuará publicando builds oficiales del Entity Framework como un producto soportado de Microsoft tanto como producto aparte como producto integrado con Visual Studio (al igual que hoy). Continuará siendo atendido por el mismo equipo de desarrolladores de Microsoft y será soportado por los mismos mecanismos de soporte de Microsoft. La meta con este anuncio es incrementar el feedback más aún, permitiéndonos conseguir un producto mejor.

El equipo está muy contento con este movimiento. Veréis nuevas características en las versiones que se suban muy pronto.

Aprende más

Ojead el sitio en CodePlex del Entity Framework para aprender e involucraros. Mirad también la página con el roadmap de EF6 en el sitio de CodePlex para enteraros de lo que va a venir en la próxima versión. Y leed sobre el nuevo Microsoft Open Tech Hub y algunos cambios en los procesos que estamos haciendo con la comunidad open source.

Espero que sirva,

Scott.

Traducido por: Juan María Laó Ramos.

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.