.net

MAD.NUG: Windows 8 y Metro para desarrolladores .NET

Windows 8

Tema nuevo para MAD.NUG y tema de actualidad.

Al caer está Windows 8, y muchos son los cambios que van a llegar con él.

Los usuarios van a notar esos cambios en la interfaz de usuario, pero los desarrolladores debemos estar al tanto de esos cambios para poder crear aplicaciones que permitan sacar el mayor provecho a la nueva versión de Windows.

Roberto Luis Bisbe nos dará en esta ocasión una interesantísima charla en la que veremos las novedades que trae el nuevo sistema operativo de Microsoft para nosotros, desarrolladores e ingenieros de Software. Hablaremos del lenguaje de diseño Metro y como cambia la experiencia de usuario. Repasaremos las herramientas, características específicas y los lenguajes disponibles para hacer nuestros programas, y veremos qué cambios se nos presentan en .Net Framework para finalmente, ver cómo monetizar nuestras aplicaciones a través de Windows Store.

El evento tendrá lugar el próximo 28 de Marzo de 2012 en las oficinas de Microsoft en Pozuelo de Alarcón (Madrid) desde las 19:00 horas hasta las 21:00 horas.

El evento es gratuito.

¡No faltes!

Podrás registrarte en http://madriddotnet.wordpress.com/2012/03/14/evento-windows-8-y-metro-para-desarrolladores-net/.

P.D.: recuerda que tal y como ha hecho Roberto, sí quieres dar una charla en MADNUG, serás bienvenido. No dudes en ponerte en contacto con nosotros y proponnos un tema.

Autenticación con Windows Live ID

Alrededor de 500 millones de personas utilizan los servicios de Windows Live, con la intención de despreocuparnos de la autenticación y ofrecer una mejor usabilidad al visitante, podemos utilizar estos servicios en nuestra web.

El primera paso es registrar nuestra página web o aplicación en http://manage.dev.live.com, indicaremos una descripción, tipo y dominio. si corresponde, donde se alojará la aplicación. Podemos registrar hasta 100 aplicaciones por cada usuario.

image

image

Estos serán los datos que configuraremos más tarde en nuestra aplicación.

Para comenzar utilizaremos el SDK de Windows Live ID Web Authentication con el que podremos iniciar una pequeña prueba de acceso. Un paso importante es copiar la carpeta App_Code dentro del directorio Sample, esta carpeta contiene “WindowsLiveLogin.vb”, encargada de la autenticación y captura de los identificadores proporcionados por Windows Live.

Por último vamos a asignar al sitio “Client ID” y el “Secret key” obtenidos anteriormente, sustituyendo los valores por defecto que vienen en el fichero web.config.

image

Todo listo, nuestra aplicación ya puede ser ejecutada. Como podéis observar nos aparece la opción Sign In, significa que no ha detectado ningún usuario, por lo que pulsando sobre el enlace nos mostrará la pantalla de autenticación.

image

image

Como podemos observar el enlace directamente conecta con Windows Live para solicitar los datos de acceso. Una vez introducidos los datos, regresaremos a nuestra aplicación, ahora el botón “Sign In” se cambiará “Sign Out” y se muestra el ID del usuario identificado, este valor siempre será el mismo para todas las ocasiones que el usuario se identifique.

 

Para más información visite Connect with Windows Live y Registering Your Application with Windows Live

Conocer la resolución de la pantalla actual

El siguiente código permite al usuario recuperar la resolución de pantalla principal.

 
MessageBox.Show("Tamaño monitor principal:" & SystemInformation.PrimaryMonitorSize.ToString)

 

También se puede obtener la resolución virtual actual, cuando se utilizan varios monitores.

 

MessageBox.Show("Tamaño pantalla virtual: " & SystemInformation.VirtualScreen.ToString)

Propiedades Environment.Is64BitOperatingSystem y Environment.Is64BitProcess en Net 4.0

Como ampliación a la anterior entrada Cómo detectar un sistema de 32 ó 64 bits, Microsoft ha implementado en Net 4.0 dos nuevas propiedades para conocer la plataforma del sistema operativo y si nuestra aplicación esta ejecutándose en un entorno de 64 bits.

Environment.Is64BitOperatingSystem indica si el sistema operativo sobre el que esta ejecutándose es de 64 bits y Environment.Is64BitProcess devuelve un True si el proceso es de 64 bits.

Disponible Visual Studio 2010 Beta 2 para MSDN

Acaban de poner a diposición de los suscriptores de MSDN la descarga de la Beta 2 de Visual Studio 2010, a parte de tener una nueva versión para realizar pruebas, que estará disponible para el público en general a partir del 21 de octubre, la novedad más importante es que ya podremos descargar y probar Team Foundation Server Basic, dentro del paquete Visual Studio Team Foundation Server 2010.

También han incluido cambios en la nomenclatura de las diferentes versiones del producto, sustituyendo la versión Team System por Ultimate.

Más información:

http://geeks.ms/blogs/lfraile/archive/2009/10/19/ya-tenemos-beta-2-de-visual-studio-2010-o-el-rey-ha-muerto-viva-el-rey.aspx

Cómo generar metodos Begin/End en servicios web con Visual Studio 2005 o superior

A todos nos ha pasado que cuando cambiamos la versión de Visual Studio o creamos nuevos proyectos desde una versión más reciente de VS, nos hemos encontrado con opciones que ya no están disponibles por defecto.

Uno de estos casos es la generación de los métodos Begin y End para la realización de llamadas asincronas hacía el WS. La cuestión es que ya está implementado el método nombrefuncionAsync por lo que ya no sería necesario Begin y End, pero cuando queremos utilizar código anterior nos encontramos con este problema.

Lo que debemos hacer es modificar el proyecto de VS que va a consumir el WS (proyecto.vbproj) con el block de notas o con un editor de XML para modificar la sección PropertyGroup añadiendo la propiedad:


True

Una vez modificado el fichero debemos lanzar la opción para Actualizar la referencia web para que se generen los métodos comentados.

Cómo detectar un sistema de 32 ó 64 bits

IntPtr es utilizado nativamente en .Net, por eso el tamaño de su estructura se redimensiona según la capacidad del sistema operativo. Utilizando esta funcionalidad podemos detectar si el sistema operativo trabaja con procesadores de 32 bits o 64 bits, ya que entonces el tamaño de la estructura de IntPtr será de 4 bits en el caso de 32 bits y 8 bits en 64 bits.

' Código VB.Net 
If IntPtr.Size = 8 Then

    ' Máquina con procesador de 64 bits

ElseIf IntPtr.Size = 4 Then

    ' Máquina con procesador de 32 bits

End If

 

// Código C#
if(IntPtr.Size == 8) 
{
    // Máquina con procesador de 64 bits
} 
else if(IntPtr.Size == 4) 
{
    // Máquina con procesador de 32 bits
}

Marcar una función como obsoleta

En ocasiones, sobre todo cuando trabajamos en equipos de desarrollo distribuidos o trabajando en diferentes partes del mismo software, debemos indicar de alguna manera la conveniencia de actualizar las llamadas a alguna función, bien sea por que hay otra función más potente y actualizada para realizar el mismo proceso y/o porque será eliminada.

Visual Studio provee una manera sencilla de “crear este aviso” para el resto de desarrolladores, incluyendo la clausula Obsolete.

' Código Visual Basic
<Obsolete("Esta función es obsoleta, por favor utilice CheckComputer", False)> _
Function CheckSystem() As String

// Código C#
[Obsolete("Esta función es obsoleta, por favor utilice CheckComputer")]
Public string CheckSystem

El que una función o clase esté marcada como obsoleta, no nos impide utilizarla, ya que por defecto, muestra una advertencia o warning en la lista de errores.

Para lograr que el compilador nos marque un error y no una advertencia cuando utilizamos la función obsoleta CheckSystem, debemos cambiar la definición de la función indicando en el parámetro Error el valor True.

' Código Visual Basic
<Obsolete("Esta función es obsoleta, por favor utilice CheckComputer", True)> _
Function CheckSystem() As String

// Código C#
[Obsolete("Esta función es obsoleta, por favor utilice CheckComputer", True)]
Public string CheckSystem

For Each en Parallel Extensions

En el artículo anterior hemos podido ver como utilizar el bucle For para acelerar la ejecución de cada iteración con Parallel.For, esta claro que cuanto más lento sea el proceso que debe realizar en cada iteración y cuanto mayor sea el número de vueltas del bucle, mayor será la diferencia entre usar los diferentes núcleos del sistema o no utilizarlos.

Otra funcionalidad que provee esta nueva clase, es para acelerar la utilización de For Each, sustituyéndolo por Parallel.ForEach.

En este ejemplo podemos observar como se muestra el listado de ficheros contenidos en C:Windows, realizando una espera de 1 segundo entre cada visualización.

Sub Main()
    Dim sw As Stopwatch
    sw = Stopwatch.StartNew()

    Dim Archivos As String() = Directory.GetFiles("C:Windows")

    For Each Fichero As String In Archivos
        Mostrar(Fichero)
    Next
    Console.WriteLine("Tiempo consumido: " & sw.ElapsedMilliseconds.ToString())

    Console.WriteLine("Pulsa para iniciar...")
    Console.ReadLine()

    sw = Stopwatch.StartNew()

    Parallel.ForEach(Archivos, Function(ip As String) Mostrar(ip))

    Console.WriteLine("Tiempo consumido: " & sw.ElapsedMilliseconds.ToString())
    Console.ReadLine()
End Sub
Function Mostrar(ByVal Fichero As String) As Boolean
    Thread.Sleep(1000)
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() & " " & Fichero)
End Function

Los tiempos obtenidos han sido de 62006 para el bucle “normal” y de 17055 para el bucle con administración automática de tareas, con esto observamos nuevamente la mejora de rendimiento que obtenemos utilizando Parallel Extensions.

Aunque para ver realmente el trabajo que realiza el procesador, deberíamos hacerle trabajar, ya que Thread.Sleep no consume procesador y no se ve claramente los núcleos que utiliza del procesador.

Os propongo que modifiquéis la función Mostrar por está que os pongo a continuación y observéis el Rendimiento de los núcleos.

Function Mostrar(ByVal Fichero As String) As Boolean
    For iC As Integer = 0 To 99999999
    Next
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() & " " & Fichero)
End Function

Inicios con Parallel Extensions

Debido a la proliferación de procesadores de núcleos múltiples, los picatecla desarrolladores tenemos que plantearnos seriamente el cambio de “mentalidad” para aprovechar todo el potencial de estos nuevos ordenadores.

Cualquiera que haya trabajado con Thread recordará que no era nada sencillo asignar diferentes hilos a algún proceso, recoger el resultado, mezclarlo para reconstruir la versión final, no es el caso de este artículo.

Por ello uno de mis objetivos para el nuevo año es la utilización o aprendizaje de Microsoft Parallel Extensions to .NET Framework 3.5, de momento como añadido, pero que estará integrado nativamente en el .NET Framework 4.0, que nos va a permitir trabajar a alto nivel con la programación concurrente y el paralelismo. A partir de entonces utilizaremos el concepto Task en lugar de Thread. Una Task se encargar de dividir el trabajo y lanzar un número óptimo de threads basándose en el número de núcleos que tengamos, evitando el overhead.

También provee de una nueva clase estática, Parallel, que nos permitirá bucles, que no dependan de datos compartidos entre cada iteración, dejando a Parallel Extensions que se encargue de crear las Tasks necesarias para concluir el proceso utilizando todo el potencial de los procesadores o núcleos del sistema.

Aún siendo un ejemplo trivial, se puede ver la mejora de rendimiento en el segundo bucle, siendo exponencial en función del número de iteraciones a realizar.

Sub Main()
    Dim sw As Stopwatch
    sw = Stopwatch.StartNew()

    For iC As Integer = 0 To 30
        Proceso(iC)
    Next
    Console.WriteLine("Tiempo consumido: " & sw.ElapsedMilliseconds.ToString())

    sw = Stopwatch.StartNew()

    Parallel.For(0, 31, Function(iC As Integer) Proceso(iC))

    Console.WriteLine("Tiempo consumido: " & sw.ElapsedMilliseconds.ToString())
    Console.ReadLine()
End Sub
Function Proceso(ByVal iC As Integer) As Boolean
    Console.WriteLine("Indice: " & iC.ToString & " - " & Thread.CurrentThread.ManagedThreadId.ToString())
    Thread.Sleep(ic)
End Function

En este ejemplo se puede observar el resultado, con 30 iteraciones, el tiempo del primer bucle es de 475 y del segundo 287, lo más importante es ver que el primer bucle se genera siempre en el “hilo” 9 y el segundo bucle utiliza varios “hilos” para concluir el proceso más rápidamente.

image

Lo más representativo es ver la gráfica de uso del CPU, se puede observa que el primer bucle (marcado en rojo), no aprovecha todo el procesador, más bien, no aprovecha todos los núcleos disponibles, sin embargo el segundo (en amarillo), mantiene durante todo el bucle el procesador al 100% exprimiendo todos los recursos existentes en ese momento.

graficaparallel

Para este ejemplo he usado un código mucho más “vulgar” para forzar el uso del procesador.

Sub Main()
    Dim sw As Stopwatch
    sw = Stopwatch.StartNew()

    For iC As Integer = 0 To 1000
        Proceso(iC)
    Next
    Console.WriteLine("Tiempo consumido: " & sw.ElapsedMilliseconds.ToString())

    Console.WriteLine("Fin del primer bucle, Pulsa para continuar...")
    Console.ReadLine()

    sw = Stopwatch.StartNew()

    Parallel.For(0, 1001, Function(iC As Integer) Proceso(iC))

    Console.WriteLine("Tiempo consumido: " & sw.ElapsedMilliseconds.ToString())
    Console.ReadLine()
End Sub
Function Proceso(ByVal iC As Integer) As Boolean
    For jC As Integer = 0 To 9999999

    Next
End Function

Todas estas pruebas han sido realizadas sobre un Intel Core2 Duo T8300 a 2,40 Ghz, cuantos más núcleos disponga el ordenador o servidor sobre el que utilicemos esta técnica, más se notará el rendimiento del conjunto.

Más información en:

http://msdn.microsoft.com/en-us/concurrency/default.aspx