Archivo de la etiqueta: .NET

TFS, Xamarin y MSTests

Hace un tiempo vimos un pequeño truco para poder ejecutar tests en las builds de TFS para proyectos Windows Phone.

Me ha sido necesario hacer lo mismo con proyectos con Xamarin Android y Xamarin iOS y aquí os pongo mi experiencia y cómo lo he resuelto. Sigue leyendo

TFS, Windows Phone y MSTests

¿Quieres que en las builds que tengas configuradas en TFS se ejecuten los test de tu aplicación Windows Phone?

Seguramente habéis probado a incluir un proyecto del tipo "Windows Phone Unit Test App" y os habéis puesto a crear nuestros tan amados tests. Pero a la hora de incluirlo en el repositorio de código, os habréis dado cuenta de que pasa algo raro: Los test no se ejecutan. (Si no te has dado cuenta, deja de leer esto y ve a comprobarlo)

La cosa es que ese proyecto de test lanza un emulador de WP y ejecuta los test y eso TFS no lo soporta todavía. Así que tienes dos opciones:

1) Dejar de hacer tests de tu aplicación WP.

2) Continuar leyendo.

Bien, si estás aquí, te cuento la solución en unos cuantos pasos:

1) Añade un proyecto de test típico de Visual Studio: Visual Studio Unit Test Project.

2) A este proyecto de test, añade una referencia del proyecto Windows Phone 8 que estés desarrollando.

3) Añade una copia local de los assemblies de Windows Phone que necesites, por ejemplo:

- System.Windows

- Microsoft.Phone

Los encontrarás en el directorio C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\MDILXAPCompile\Framework

4) Copialos a un directorio local, que también tendrás que subir al TFS, llámalo por ejemplo /lib/ y ahora edita el XML del proyecto de test (el .csproj) y reemplaza:

<Reference Include="System.Windows" />
<Reference Include="Microsoft.Phone" />

por:

  <Reference Include="System.Windows, Version=2.0.6.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, processorArchitecture=MSIL">
  <HintPath>lib\System.Windows.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Phone, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e, processorArchitecture=MSIL">
  <HintPath>lib\Microsoft.Phone.dll</HintPath>
</Reference>

Además, para evitar los warnings cada vez que compiles añade este elemento al primer grupo de <PropertyGroup> del .csproj:

<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>

A partir de este momento, cuando incluyáis vuestro proyecto en vuestro TFS vuestros tests se ejecutarán como si lo hiciesen en el emulador, pero sin tener que lanzarlos.

Espero que pronto den solución a este "problema" y lo incluyan en la próxima versión.

Este post ha sido gracias a una respuesta en stackoverflow http://stackoverflow.com/a/13035195 que me ha salvado el día.

¿Se os ocurre otra forma de conseguir el mismo resultado?

Espero que sirva.

Juan María Laó Ramos.

[ebook] Testing Unitario con Microsoft Fakes

Hace un tiempo encontré un recurso que me pareció bastante interesante de compartir con la comunidad hispano-hablante.

Me lié la manta a la cabeza y fui traduciéndolo poco a poco. Y gracias a Jose Bonnin (@wasat) y a los Visual Studio ALM Technical Rangers aquí tenéis el resultado:

MicrosoftFakes

Post en el blog de los Visual Studio ALM Technical Rangers: http://blogs.msdn.com/b/willy-peter_schaub/archive/2013/08/22/191-habla-espa-241-ol-testing-unitario-con-microsoft-174-fakes.aspx

Espero que sirva.

Una experiencia ALM ++

En estos últimos tres meses he tenido la oportunidad de aplicar Scrum y TDD de manera estricta.

Ha sido una experiencia muy enriquecedora y la voy a compartir con todos.

En el proyecto hemos usado Team Foundation Service y Visual Studio 2012 como solución ALM con la plantilla por defecto de Scrum. Con esto solventamos varias cosas de un plumazo:

  • Gestión del Backlog
  • Definición de Sprints
  • Gestión de Tareas.
  • Gestión de Bugs.

La interacción con el cliente también la hacíamos a través de la web del proyecto.

Lo que más me llamó la atención fué lo fácil que es la gestión de bugs. Cuando el cliente encontraba un bug, lo abría y le ponía la prioridad, el scrum Master lo comunicaba en el daily scrum y nos organizábamos para ver quién lo corregía

ALM

  • Teníamos definidas varias Builds para cada parte del sistema que lanzaba una compilación y ejecución de los Test Unitarios que había para asegurar que no se había roto nada.
  • También había otra serie de Builds manuales necesarias para generar una versión para desplegar en los distintos entornos Desarrollo, Pre-producción y Producción.

La verdad que esto de no salir de Visual Studio para crear un sistema es una bendición. En su día integré Jenkis, Trac y Subversion en un proyecto en .NET, me maravillaba lo que se podia hacer con estas herramientas. La verdad es que me costó un tiempo montarlo y después mantenerlo.

Y en una conversación con el Scrum Master me soltó esto:

“Luego te llegan los empalmados que si Subversion, Jenkins, Jira, Trac, Bugcilla, que es gratis. Si estás desarrollando en .NET, el intentar integrar todo eso para que funcione con .NET es posible, pero es cuestión de tiempo y dinero”

Y en estos tres meses de trabajo, le habremos dedicado 40 horas a estos temas (daily scrums incluidos) y todo sin salir de Visual Studio.

[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()
        {
        }
    }

    static GameEntity[] entities = new GameEntity[100];
    static Program()
    {
        for (int i = 0; i < entities.Length; i++)
        {
            entities[i] = new GameEntity();
        }
    }

    static void Main(string[] args)
    {
        byte[] byteArray = new byte[1];
        for (int i = 0; i < entities.Length; i++)
        {
            entities[i].Update();
        }
    }
}

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!

Hackathon Windows 8

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.

Windows Azure Media Services

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.

- Primer camino para alcanzar el Nirvana del Garbage Colector.

- Segundo camino para alcanzar el Nirvana del Garbage Colector y cual elegir.

- Delegados, eventos y basura. (Próximamente).

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). Sigue leyendo