Mostrando las entradas con la etiqueta Strings. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Strings. Mostrar todas las entradas

lunes, 26 de septiembre de 2016

El Libro del Día: Understanding ECMAScript 6

El Libro del Día: 2016-09-26

Titulo: Understanding ECMAScript 6
Autor: Nicholas C. Zakas
Editorial: No Starch Press
Nro Paginas: 355

Capítulos:
Chapter 1: Block Bindings
Chapter 2: Strings and Regular Expressions
Chapter 3: Functions
Chapter 4: Expanded Object Functionality
Chapter 5: Destructuring for Easier Data Access
Chapter 6: Symbols and Symbol Properties
Chapter 7: Sets and Maps
Chapter 8: Iterators and Generators
Chapter 9: Introducing JavaScript Classes
Chapter 10: Improved Array Capabilities
Chapter 11: Promises and Asynchronous Programming
Chapter 12: Proxies and the Reflection API
Chapter 13: Encapsulating Code with Modules
Appendix A: Minor Changes in ECMAScript 6
Appendix B: Understanding ECMAScript 7 (2016)

Descarga:
Understanding_ECMAScript_6

miércoles, 27 de julio de 2016

El Libro del Día: Professional C# 6 and .NET Core 1.0

El Libro del Día: 2016-07-27

Titulo: Professional C# 6 and .NET Core 1.0
Autor: Christian Nagel
Editorial: Wrox
Nro Paginas: 1532

Capítulos:
Part I: The C# Language
Chapter 1 .NET Application Architectures
Chapter 2 Core C#
Chapter 3 Objects and Types
Chapter 4 Inheritance
Chapter 5 Managed and Unmanaged Resources
Chapter 6 Generics
Chapter 7 Arrays and Tuples
Chapter 8 Operators and Casts
Chapter 9 Delegates, Lambdas, and Events
Chapter 10 Strings and Regular Expressions
Chapter 11 Collections
Chapter 12 Special Collections
Chapter 13 Language Integrated Query
Chapter 14 Errors and Exceptions
Chapter 15 Asynchronous Programming
Chapter 16 Reflection, Metadata, and Dynamic Programming
Part II: .NET Core and Windows Runtime
Chapter 17 Visual Studio 2015
Chapter 18 .NET Compiler Platform
Chapter 19 Testing
Chapter 20 Diagnostics and Application Insights
Chapter 21 Tasks and Parallel Programming
Chapter 22 Task Synchronization
Chapter 23 Files and Streams
Chapter 24 Security
Chapter 25 Networking
Chapter 26 Composition
Chapter 27 XML and JSON
Chapter 28 Localization
Part III: WINDOWS APPS
Chapter 29 Core XAML
Chapter 30 Styling XAML Apps
Chapter 31 Patterns with XAML Apps
Chapter 32 Windows Apps: User Interfaces
Chapter 33 Advanced Windows Apps
Chapter 34 Windows Desktop Applications with WPF
Chapter 35 Creating Documents with WPF
Chapter 36 Deploying Windows Apps
Part IV: Web App lications and Services
Chapter 37 ADO.NET
Chapter 38 Entity Framework Core
Chapter 39 Windows Services
Chapter 40 ASP.NET Core
Chapter 41 ASP.NET MVC
Chapter 42 ASP.NET Web API
Chapter 43 WebHooks and SignalR
Chapter 44 Windows Communication Foundation
Chapter 45 Deploying Websites and Services

Descarga:
Professional_C#_6_and_.NET_Core_1.0

martes, 7 de julio de 2015

Entrenamiento - Inicio del .NET Developer

Inicio del .NET Developer (The Best Practices for Performance)

Quiero anunciar el inicio del programa .NET Developer el cual tendra un solo horario, los Sabados en las Tardes de 3:00 pm a 9:00 pm. y la fecha de inicio es el 01 de Agosto. Los que eligieron el horario del Domingo este se ha cancelado por no llegar al mínimo necesario para iniciar y los que desean pueden pasarse al horario de los Sabados en la Tarde, previa confirmación por mail.

Modulo 1: Windows Developer (72 horas en 3 meses)
Fundamentals
Curso 01: .NET Framework (18 horas)
Curso 02: ADO .NET (18 horas)
Windows Applications
Curso 03: WinForms  (18 horas)
Curso 04: WPF  (18 horas)

Modulo 2: Web Developer (72 horas en 3 meses)
Back End
Curso 05: ASP.NET MVC (18 horas)
Curso 06: Servicios (WCF y Web API) (18 horas)
Front End
Curso 07: JavaScript (DOM, jQuery, AJAX) (18 horas)
Curso 08: HTML5 (APIs) (18 horas)

Modulo 3: Mobile Developer (72 horas en 3 meses)
Web Mobile
Curso 09: Responsive Web Designe (CSS3+HTML5+MVC) (18 horas)
Curso 10: jQuery Mobile (18 horas)
Native Apps
Curso 11: Xamarin Forms iOS (18 horas)
Curso 12: Xamarin Forms Android (18 horas)

Estándares y Malas Prácticas de Desarrollo Web

La mayoria de desarrolladores confunde el Estándar con las Buenas Prácticas, a continuación una lista de temas que considero Estándares y Malas Prácticas de Desarrollo:
- Entity Framework
- LINQ
- DataSets y DataTables
- Abuso de Librerías de JavaScript (jQuery, jQueryUI, Kendo, etc)
- Abuso de Frameworks de Responsive Web Design (Bootstrap, jQuery Mobile, etc)
- Abuso de Controles de Terceros (Infragistics, Telerik, DevExpress, etc)
- Reporteadores de Datos (Crystal Reports, ReportViewer)
- Formatos de Datos: XML, JSON
- Todo Orientado a Servicios: Servicios Web XML, WCF, Web API, etc.
- Trabajar en forma Síncrona, No Concurrente y con un Solo Procesador.

Muchos se preguntaran que tienen de malo, el usar esas características, la respuesta es que afectan considerablemente la performance. Yo en clases demuestro la diferencia en Tiempo de Procesamiento y Memoria (Performance) para que no quede ninguna duda, pero lamentablemente solo mis alumnos pueden ver dichas comparaciones.

Buenas Prácticas de Desarrollo Web (Performance)

Es lo que proponemos para desarrollar en .NET o en cualquier plataforma, usar lo nativo, lo que ya viene de base, por ejemplo en .NET, el reemplazo del estándar sería:
- ADO .NET
- Predicados
- Listas de Objetos
- JavaScript y APIs de HTML5 (ejemplo asíncrono con XmlHttpRequest en vez de jQuery)
- Crear tu propio archivo CSS Responsivo.
- Crear tus propios Controles que devuelvan la menor cantidad de HTML
- Crear tu propio Reporte con JavaScript, HTML, Drawing, Canvas, etc
- Formato de Datos Personalizado (Strings)
- Exponer como Servicios solo lo necesario (para otras plataformas), mejor es usar Librerías (No hay serialización si esta local o si es remota interna lo aconsejable es Binario con TCP), etc.
- Trabajar en forma Asíncrona, Concurrente y Paralela (todos los Procesadores).

Todos nos preguntamos porque las paginas web que desarrollamos son tan lentas y buscamos la solución en Hardware (mas memoria, mas procesador, mas Disco, mas Servidores, etc) cuando el Problema de la Performance es básicamente Software, es decir, nuestro código.

Comentario Final

Si tu experiencia como desarrollador es usar los estándares descritos anteriormente, entonces, te conviene capacitarse en el Programa .NET Developer que inicio en Agosto, ya que es el único en nuestro país que tiene un enfoque fuera del tradicional, yo enseño a que aprendas a Crear tu mismo todo y  no a usar cosas que estan mal creadas.

Los que ya llevaron alguna vez conmigo, sobre todo hace mas de un año; los contenidos, el enfoque y los demos son totalmente distintos.

Finalmente, recalcar que por ahora habrá un solo grupo que será los Sabados en la Tarde y la Inversión menual es de 360 soles, lo que es muy económico respecto a lo que van a aprender. Actualmente, muchos pagan mucho mas para que les enseñen cosas que no sirven para nada, es por eso que la mayoría de sitios web dan pena (sino me creen pasenle el Test de YSlow y PageSpeed).

Solo quedan 5 vacantes para iniciar, los interesados pueden confirmar su inscripción por mail a Luis.duenash@gmail.com. En cuanto al pago se hará el mismo día y en cuanto al local les enviaré por mail (solo a los registrados).

Los que este año hubieran llevado conmigo, pueden dar sus comentarios para animar a los que todavía dudan que tan bueno es el curso y quieran compararlo con otros cursos de .NET.

Videos - Curso ASP.NET MVC Editora Perú (Parte 1)

Videos del Curso de ASP.NET MVC en Editora Perú (Parte 1)

Comparto la primera parte del Curso de ASP.NET MVC realizado en Editora Perú (Diario El Peruano y Agencia de Noticias Andina), en donde casi todos los demos son en forma asíncrona con la mejor performance (XmlHttpRequest y Strings).

Demo 10 - Consulta Conectada Sincrona con Todo el HTML

En este video se muestra una aplicación que permite filtrar los productos por categoría en forma conectada, es decir, consultando en cada momento a la base de datos usando librerías.

Para mostrar los datos del filtro se vuelve a mostrar la Vista completa, es decir todo el HTML, por lo cual se ve el parpadeo.


Demo 11 - Consulta Conectada Asincrona con Ajax Form y Vista Parcial

En este video se muestra una aplicación que permite filtrar los productos por categoría en forma conectada, es decir, consultando en cada momento a la base de datos usando librerías.

A diferencia del demo anterior, la consulta es asíncrona usando un Formulario Ajax y una Vista Parcial que solo muestra la tabla de productos, por lo que no ocurre el parpadeo.


Demo 12 - Consulta Conectada Asincrona con jQuery Ajax y JSON

En este video se muestra una aplicación que permite filtrar los productos por categoría en forma conectada, es decir, consultando en cada momento a la base de datos usando librerías.

A diferencia del demo anterior, la consulta es asíncrona usando jQuery Ajax y JSON que disminuye los datos enviados al cliente en casi la mitad con respecto a la vista parcial.


Demo 13 - Consulta Conectada Asincrona con jQuery Ajax y String

En este video se muestra una aplicación que permite filtrar los productos por categoría en forma conectada, es decir, consultando en cada momento a la base de datos usando librerías.

A diferencia del demo anterior, la consulta es asíncrona usando jQuery Ajax y Strings para lo cual se crea un Serializador que permite convertir la Lista de Objetos en Cadenas separadas por un delimitador de campos y otro de registros.

Esta técnica permite reducir los datos enviados al cliente en casi la tercera parte con respecto a JSON, es decir, el HTML es el 100%, Vista Parcial 50%, JSON 25% y Strings 8%. Esta última tecnica que propongo es la máxima en Performance.


Demo 14 - Consulta Desconectada Parcial Asincrona con jQuery Ajax y String

En este video se muestra una aplicación que permite filtrar los productos por categoría en forma desconectada parcial, es decir, desconectada de la base de datos, pero conectada al servidor web.

La consulta es asíncrona usando jQuery Ajax y Strings para lo cual se crea un Serializador que permite convertir la Lista de Objetos en Cadenas separadas por un delimitador de campos y otro de registros.

En el Servidor Web los datos se guardan en un TempData al inicio y luego se recuperan cada vez que se filtra, viajando solo una cadena conteniendo los productos por categoría.


Demo 15 - Consulta Desconectada Total Asincrona con jQuery Ajax y String

En este video se muestra una aplicación que permite filtrar los productos por categoría en forma desconectada total, es decir, desconectada de la base de datosy del servidor web.

La consulta es asíncrona usando jQuery Ajax y Strings para lo cual se crea un Serializador que permite convertir la Lista de Objetos en Cadenas separadas por un delimitador de campos y otro de registros.

Todos los datos de categorias y productos se envian al cliente, pero solo se guardan los productos para poder filtrarse por JavaScript.


Los alumnos que alguna vez llevaron conmigo ASP.NET MVC, se daran cuenta que la forma como estamos programando es un poco diferente, ya que uso mas JavaScript y menos C#.

jueves, 4 de junio de 2015

El Demo del Día: Performace entre Serializadores .NET

Performace entre Serializadores .NET

El Problema de la Performance

Uno de los problemas principales de los Sistemas Informáticos Modernos es la Performance, sea Windows o Web la Aplicación, con el crecimiento del uso (aumento de usuarios) dentro (Intranet) y fuera de la empresa (Internet) las aplicaciones cada vez son mas lentas.

Esta lentitud es tratada de resolver aumentando Hardware como mas Servidores, mas Memorias, mas CPUs, mas Ancho de Banda, etc. Todo menos hacer una reingeniería del desarrollo que es la principal causa, es decir el problema es la forma cómo se programa (Software) donde lo común es que se realizan muchas conexiones al Servidor de Base de Datos, se usan estructuras de datos pesadas (por ejemplo en .NET los DataSets), se hacen bucles expensivos, etc.

Solución al Problema de la Performance

Aprender las Buenas Prácticas de Programación que permitan consumir la menor cantidad de memoria con el menor tiempo de procesamiento, para lo cual hay diferentes las cuales compartiremos a partir de hoy, empezando por una Comparación de Serializadores para elegir el mejor.

Definición de Serialización

Según Wikipedia, la Serialización (o Marshalling en inglés) es el proceso de codificación de un objeto en un medio de almacenamiento (como puede ser un archivo, o un buffer de memoria) con el fin de transmitirlo a través de una conexión en red como una serie de bytes o en un formato humanamente más legible como XML o JSON, entre otros.

La serie de bytes o el formato pueden ser usados para crear un nuevo objeto que es idéntico en todo al original, incluido su estado interno (por tanto, el nuevo objeto es un clon del original).

La Serialización es un mecanismo ampliamente usado para transportar objetos a través de una red, para hacer persistente un objeto en un archivo o base de datos, o para distribuir objetos idénticos a varias aplicaciones o localizaciones.

Importancia de elegir un Serializador

Es necesario saber elegir adecuadamente un Serializador, ya que cada vez que enviamos datos entre dos procesos se usa la serialización. 

A continuación listamos los Serializadores .NET junto con los tipos de aplicaciones o tecnologías distribuidas que las usan por defecto:

- Serializador Binario: Usado en Sockets y .NET Remoting (dll)
- Serializador SOAP: Usado por Servicios Web XML (asmx)
- Serializador XML: Usado por los Servicios WCF (svc y dll)
- Serializador JSON: Usado en Web API
- Serializador Personalizado: Hay que crearlo uno mismo.

La importancia de seleccionar bien el Serializador es que este es el factor principal de performance al momento de usar un Servicio o una Aplicación Distibuida, es decir, depende de este el tiempo de serialización deserealización y sobre todo el formato y el tamaño de los datos que se pasan por la red.

En este post, comprobaremos cual es el mejor, sin embargo la mayoría siempre usa el peor y después quiere que sus Servicios sean rápidos, es decir, quieren una cosa (Performance) pero hacen otra (Estándar).

Crear una Aplicación Windows Forms en C#

Abrir Visual Studio y crear una aplicación Windows Forms en C# llamada "Comparacion_Serializacion", cambiarle de nombre al formulario por "frmListaProductos" y realizar el diseño similar a la figura mostrada:


Nota: En el diseño hay un DataGridView llamado "dgvProducto", un menú contextual llamado "mnuContextual" con 6 opciones: mnuCargarDatos, mnuBinario, mnuSOAP, mnuXML, mnuJSON y mnuPersonalizado.

Crear el Procedimiento Almacenado en SQL Server

Crear el Procedimiento llamado "uspProductsListar" en SQL Server:

Create Procedure uspProductsListar
As
Select ProductID, ProductName, SupplierID, 
CategoryID,UnitPrice, UnitsInStock
From Products

Crear la Clase Entidad del Negocio

Agregar una clase al proyecto llamada: "beProducto" y escribir el siguiente código:

using System;
using System.Runtime.Serialization;

namespace Comparacion_Serializacion
{
    //[Serializable]
    //[DataContract]
    public class beProducto
    {
        //[DataMember]
        public int IdProducto { get; set; }
        //[DataMember]        
        public string Nombre { get; set; }
        //[DataMember]
        public int IdProveedor { get; set; }
        //[DataMember]
        public int IdCategoria { get; set; }
        //[DataMember]
        public decimal PrecioUnitario { get; set; }
        //[DataMember]
        public short Stock { get; set; }
    }
}

Nota: Los atributos de serialización (Serializable, DataContract y DataMember) han sido comentados inicialmente para ver que sucede cuando se intenta serializar con cada técnica.

Crear la Clase de Acceso a Datos

Agregar una clase al proyecto llamada: "daProducto" y escribir el siguiente código:

using System;
using System.Collections.Generic; //List
using System.Data; //CommandType, CommandBehavior
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader

namespace Comparacion_Serializacion
{
    public class daProducto
    {
        public List<beProducto> listar(SqlConnection con)
        {
            List<beProducto> lbeProducto = null;

            SqlCommand cmd = new SqlCommand("uspProductsListar", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
            if (drd != null)
            {
                lbeProducto = new List<beProducto>();
                int posIdProducto = drd.GetOrdinal("ProductID");
                int posNombre = drd.GetOrdinal("ProductName");
                int posIdProveedor = drd.GetOrdinal("SupplierID");
                int posIdCategoria = drd.GetOrdinal("CategoryID");
                int posPrecioUnitario = drd.GetOrdinal("UnitPrice");
                int posStock = drd.GetOrdinal("UnitsInStock");
                beProducto obeProducto;
                while (drd.Read())
                {
                    obeProducto = new beProducto();
                    obeProducto.IdProducto = drd.GetInt32(posIdProducto);
                    obeProducto.Nombre = drd.GetString(posNombre);
                    obeProducto.IdProveedor = drd.GetInt32(posIdProveedor);
                    obeProducto.IdCategoria = drd.GetInt32(posIdCategoria);
                    obeProducto.PrecioUnitario = drd.GetDecimal(posPrecioUnitario);
                    obeProducto.Stock = drd.GetInt16(posStock);
                    lbeProducto.Add(obeProducto);
                }
                drd.Close();
            }

            return (lbeProducto);
        }
    }
}

Crear la Clase de Reglas del Negocio

Agregar una clase al proyecto llamada: "brProducto" y escribir el siguiente código:

using System;
using System.Configuration; //ConfigurationManager
using System.Data.SqlClient; //SqlConnection
using System.Collections.Generic; //List

namespace Comparacion_Serializacion
{
    public class brProducto
    {
        public string CadenaConexion { get; set; }
        private string archivoLog;

        public brProducto()
        {
            CadenaConexion = 
                ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
        }

        public List<beProducto> listar()
        {
            List<beProducto> lbeProducto = null;
            using (SqlConnection con = new SqlConnection(CadenaConexion))
            {
                try
                {
                    con.Open();
                    daProducto odaProducto = new daProducto();
                    lbeProducto = odaProducto.listar(con);
                }
                catch (SqlException ex)
                {
                    //grabarLog(ex);
                }
                catch (Exception ex)
                {
                    //grabarLog(ex);
                }
            } //con.Close(); con.Dispose();
            return (lbeProducto);
        }
    }
}

Nota: Para usar la clase "ConfigurationManager", primero hay que hacer referencia a la librería "System.Configuration.dll"

Crear una Clase para la Serialización Personalizada de Strings

Agregar una clase al proyecto llamada: "CustomSerializer" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.IO;

namespace Comparacion_Serializacion
{
    public class CustomSerializer
    {
        public static void Serializar<T>(List<T> lista, string archivo, char separadorCampo, 
        char separadorRegistro)
        {
            StringBuilder sb = new StringBuilder();
            PropertyInfo[] propiedades = lista[0].GetType().GetProperties();
            for (int i = 0; i < propiedades.Length; i++)
            {
                sb.Append(propiedades[i].Name);
                if (i < propiedades.Length - 1) sb.Append(separadorCampo);
            }
            sb.Append(separadorRegistro);
            for (int j = 0; j < lista.Count; j++)
            {
                propiedades = lista[j].GetType().GetProperties();
                for (int i = 0; i < propiedades.Length; i++)
                {
                    if (propiedades[i].GetValue(lista[j], null) != null) 
                    sb.Append(propiedades[i].GetValue(lista[j], null).ToString());
                    else sb.Append("");
                    if (i < propiedades.Length - 1) sb.Append(separadorCampo);
                }
                if (j < lista.Count - 1) sb.Append(separadorRegistro);
            }
            File.WriteAllText(archivo,sb.ToString());
        }

        public static List<T> Deserializar<T>(string archivo, char separadorCampo, 
        char separadorRegistro)
        {
            List<T> lista = new List<T>();
            if (File.Exists(archivo))
            {
                string contenido = File.ReadAllText(archivo);
                string[] registros = contenido.Split(separadorRegistro);
                string[] campos;
                string[] cabecera = registros[0].Split(separadorCampo);
                string registro;
                Type tipoObj;
                T obj;
                dynamic valor;
                Type tipoCampo;
                for (int i = 1; i < registros.Length; i++)
                {
                    registro = registros[i];
                    tipoObj = typeof(T);
                    obj = (T)Activator.CreateInstance(tipoObj);
                    campos = registro.Split(separadorCampo);
                    for (int j = 0; j < campos.Length; j++)
                    {
                        tipoCampo = obj.GetType().GetProperty(cabecera[j]).PropertyType;
                        valor = Convert.ChangeType(campos[j],tipoCampo);
                        obj.GetType().GetProperty(cabecera[j]).SetValue(obj, valor);
                    }
                    lista.Add(obj);
                }
            }
            return (lista);
        }
    }
}

Nota: Para crear mi propio Serializador uso Reflection y Listas Genéricas. 
Una de las claves para hacer la Deserealización es crear una instancia del objeto dinámicamente con Activator.CreateInstance y luego escribir el valor desde la cadena al objeto para lo cual uso Convert.ChangeType.

Escribir el Código del Formulario frmListaProducto

Antes de escribir el código de los Serializadores hay que hacer las siguientes Referencias:
- System.Runtime.Serialization.Formatters.Soap.dll para la Serialización SOAP
- System.Runtime.Serialization para la Serialización JSON

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO; //FileStream
using System.Linq; //ToList
using System.Diagnostics; //Stopwatch
using System.Runtime.Serialization.Formatters.Binary; //BinaryFormatter
using System.Runtime.Serialization.Formatters.Soap; //SoapFormatter
using System.Xml.Serialization; //XmlSerializer
using System.Runtime.Serialization.Json; //DataContractJsonSerializer

namespace Comparacion_Serializacion
{
    public partial class frmListaProducto : Form
    {
        private List<beProducto> lbeProducto;

        public frmListaProducto()
        {
            InitializeComponent();
        }

        private void cargarDatos(object sender, EventArgs e)
        {
            brProducto obrProducto = new brProducto();
            lbeProducto = obrProducto.listar();
            dgvProducto.DataSource = lbeProducto;
        }

        private void medirTiempo(Action metodo)
        {
            Stopwatch cronometro = new Stopwatch();
            cronometro.Start();
            metodo();
            MessageBox.Show(String.Format("Tiempo de Duración: {0:n0} msg", 
            cronometro.Elapsed.TotalMilliseconds));
            cronometro.Stop();
        }

        private void serializarBinario()
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = new FileStream("Binario.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                bf.Serialize(fs, lbeProducto);
            }
        }

        private void deserializarBinario()
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = new FileStream("Binario.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=(List<beProducto>)bf.Deserialize(fs);
            }
        }

        private void serializarSOAP()
        {
            SoapFormatter sf = new SoapFormatter();
            using (FileStream fs = new FileStream("SOAP.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                sf.Serialize(fs, lbeProducto.ToArray());
            }
        }

        private void deserializarSOAP()
        {
            SoapFormatter sf = new SoapFormatter();
            using (FileStream fs = new FileStream("SOAP.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=((beProducto[])sf.Deserialize(fs)).ToList();
            }
        }

        private void serializarXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("XML.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                xs.Serialize(fs, lbeProducto);
            }
        }

        private void deserializarXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("XML.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto = (List<beProducto>)xs.Deserialize(fs);
            }
        }

        private void serializarJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("JSON.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                js.WriteObject(fs, lbeProducto);
            }
        }

        private void deserializarJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("JSON.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=(List<beProducto>)js.ReadObject(fs);
            }
        }

        private void serializarString()
        {
            CustomSerializer.Serializar(lbeProducto, "Strings.txt", ',', '|');
        }

        private void deserializarString()
        {
            lbeProducto=CustomSerializer.Deserializar<beProducto>("Strings.txt", ',', '|');
        }

        private void mnuSerializarBinario_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarBinario);
        }

        private void mnuDeserializarBinario_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarBinario);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarSOAP_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarSOAP);
        }

        private void mnuDeserializarSOAP_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarSOAP);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarXML_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarXML);
        }

        private void mnuDeserializarXML_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarXML);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerealizarJSON_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarJSON);
        }

        private void mnuDeserealizarJSON_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarJSON);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarPersonalizado_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarString);
        }

        private void mnuDeserializarPersonalizado_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarString);
            dgvProducto.DataSource = lbeProducto;
        }
    }
}

Nota: Todos las funciones manejadoras de eventos llaman a la función "medirTiempo" para ejecutar la Serialización y Deserealización.

Modificar el Archivo de Configuración

Abrir el archivo app.Config y aumentar la cadena de conexión:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="conNW" providerName="SQLServer"
      connectionString="uid=UsuarioNW;pwd=123456;
      server=DSOFT\Sqlexpress;database=Northwind"/>
  </connectionStrings>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

Ejecutar y Probar la Aplicación Windows Forms

Grabar la aplicación y pulsar F5 para ejecutarla. Aparecerá una ventana similar a la siguiente figura:


Clic derecho y se mostrará el menú contextual, del cual seleccionar la primera opción: "Cargar Datos" y se listarán los productos.


Serialización Binaria

Clic derecho y del menú contextual seleccionar la opción "Binario" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 11 msg y se creará un archivo llamado "Binario.txt" con el siguiente contenido:


Notas
- Si se intenta Serializar el archivo a Binario se caerá ya que la Entidad (clase beProducto) no es serializable, proceder a descomentar el atributo [Serializable].
- Observar que el tamaño del archivo Binario.txt es de 5756 bytes (en mi caso).

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 8 msg y se cargarán los datos desde el archivo "Binario.txt" en la lista de objetos y se mostrará en la grilla.

Serialización SOAP

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "SOAP" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 30 msg y se creará un archivo llamado "SOAP.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo SOAP.txt es de 73586 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 51 msg y se cargarán los datos desde el archivo "SOAP.txt" en la lista de objetos y se mostrará en la grilla.

Serialización XML

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "XML" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 192 msg y se creará un archivo llamado "XML.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo XML.txt es de 22270 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 209 msg y se cargarán los datos desde el archivo "XML.txt" en la lista de objetos y se mostrará en la grilla.

Serialización JSON sin atributos

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "JSON" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 474 msg y se creará un archivo llamado "JSON.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo JSON.txt es de 19716 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 347 msg y se cargarán los datos desde el archivo "JSON.txt" en la lista de objetos y se mostrará en la grilla.

Serialización JSON con atributos (DataContract y DataMember)

Detener la ejecución, decomentar los atributos [DataContract] y [DataMamber] de la entidad beProducto, además renombrar el archivo JSON.txt por JSON2.txt y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "JSON" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 27 msg y se creará un archivo llamado "JSON.txt" con el siguiente contenido:



Nota: Observar que el tamaño del archivo JSON.txt es tan solo de 10332 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 92 msg y se cargarán los datos desde el archivo "JSON.txt" en la lista de objetos y se mostrará en la grilla.

Serialización Personalizada con Strings

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "Personalizado" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 15 msg y se creará un archivo llamado "Strings.txt" con el siguiente contenido:



Nota: Observar que el tamaño del archivo Strings.txt es de 3125 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Personalizado" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 53 msg y se cargarán los datos desde el archivo "Strings.txt" en la lista de objetos y se mostrará en la grilla.

Resumen Comparativo

A continuación una figura con un cuadro resumen de tiempos y tamaños por serializador (formato):



Esta resaltado los que mejor rendimiento tienen, es decir el tiempo de Serializado el ganador es el Binario, pero en tamaño (ancho de banda) el ganador es el Strings (Personalizado), además para Servicios Web el Binario no es aplicable por tanto, el mejor Serializador en Performance sería el String.

Sin embrago el comportamiento de los desarrolladores ha sido:
- Web Services XML con SOAP (2002-2007)
- WCF Services con XML (2008-2011)
- Web API con JSON (2012-2015)

Comentario Final

Después de haber tratado detalladamente los Serializadores .NET y analizado su tiempo y tamaño, la recomendación final es que si desean consumir el mínimo ancho de banda, hay que crear su propio serializador (yo le estoy dejando el mio, que poco a poco lo voy a optimizar) ya que es el que mejor rendimiento tiene en velocidad, tamaño e inter-operabilidad.

Claro, muchos dirán que No es Estandar el formato creado, y otros dirán y como hago para consumirlos desde los clientes, es decir como muestro estos datos, así como hay Templates para JSON yo tambien tengo mis propias rutinas que muestran en JavaScript cualquier Strings separados por caracteres, los cuales serán motivos de otros post.

Descarga del Código


miércoles, 3 de junio de 2015

Videos - Tercer Taller .NET Domingos (Parte 1)

Videos del Tercer Taller .NET Domingos (Parte 1)

Comparto con los visitantes del Blog los Videos (sin audio) del Tercer Taller de los Domingos, con temas variados como .NET Remoting, Programación de Tareas, etc.

Nota: El Demo 01 es un Chat en .NET Remoting pero no fue grabado.

Demo 02 - Aplicación con NET Remoting de Login con Captcha

En este video se muestra como crear una aplicación distribuida con .NET Remoting para el CAPTCHA.

Primero se crea la librería remota, luego el servidor remoto que es una aplicación de consola y finalmente una aplicación cliente en Windows Forms.

En la aplicación cliente se llama en forma asíncrona 1000 veces el método remoto que crea el Captcha.


Demo 03 - Aplicación con NET Remoting de Actualización de Archivos

En este video se enseña como crear una aplicación remota con .NET Remoting que permita descargar y actualizar una aplicación desde un servidor a los clientes.

Para esto se crea una aplicación Windows Forms Editor que es la que se va a descargar y actualizar sus versiones. Luego creamos una Librería Remota que devuelva los bytes de la aplicación actualizada.

También creamos una aplicación de Consola que sirve de Servidor Remoto (aloja a la Librería de Actualización) y finalmente la Aplicación Cliente Windows (oculta en el Systray) que permite invocar a la librería remota y actualizar la aplicación.

Finalmente, un problema que se tuvo fue el bloqueo del archivo al usar Reflection para averiguar el Nombre y la Versión del Ensamblado para hacer la actualización, pero este se resolvió no usando la Url sino los bytes del archivo.


Demo 04 - Generador de Código .NET y Performance con Session

En este video muestro un poco sobre mi Generador de Código .NET que crea Procedimientos Almacenados, Entidades de Negocio, Capa de Acceso a Datos, Capa de Reglas del Negocio y Formularios Web Forms de forma eficiente.

También se muestra un proyecto Web de Prueba y se analiza un formulario con una grilla paginada con una tabla de mas de 250,000 registros y como al usar Session el procesador se eleva al 100%.

Se hace un análisis de la performance reduciendo los datos del Procedimiento Almacenado a 100,000 luego a 50000, después a 20,000 y 10,000 observándose que el procesador ya no se eleva.

La conclusión es que cualquier operación de lectura o escritura de un objeto Session con una Lista de Objetos que tiene mas de 20,000 registros ocasiona que el procesador se eleve demasiado, es decir, usar como límite de registros 20,000 para el Session sería lo mas adecuado.


Demo 05 - Copiador de Archivos incluyendo Subdirectorios

En este video enseño como crear una aplicación de consola que permita copiar todos los archivos junto con todos los directorios de una ruta a otra.

Luego se crea una Tarea Programada en Windows usando el Task Scheduler que permita ejecutar dicha aplicación a diario.


Demo 06 - Automatizar Programación de Tareas en .NET (Parte 1)

En este video se muestra la primera parte de una aplicación de Windows Forms que permite Automatizar la Programación de Tareas, es decir, lo que hace el Task Scheduler.

La primera parte consiste en listar todas las tareas programadas en un ListView mostrando el nombre de la tarea, su folder y su estado: en ejecución, detenido, deshabilitado, etc.

Las Tareas que pertenecen al folder DSOFT y las que están en ejecución se muestran con un color de fondo y texto diferente.


Demo 06 - Automatizar Programación de Tareas en .NET (Parte 2)

En este video se muestra la segunda parte de una aplicación de Windows Forms que permite Automatizar la Programación de Tareas, es decir, lo que hace el Task Scheduler.

En esta segunda parte se enseña como crear una nueva tarea, la cual se muestra en la lista de tareas.


Demo 07 - Optimizar Web API con Serializacion de String

Este video sin duda es uno de los mejores, ya que enseño como Optimizar un Servicio Web API usando mi propio Serializador que convierte una Lista de Objetos en cadenas separadas por un caracter los campos y otro los registros.

La técnica tradicional es usar JSON, pero en este video se observa como se reduce a mas de la mitad el tamaño de los bytes enviados desde el servidor web al cliente usando Strings.

En el cliente usamos una función de JavaScript que realiza la presentación de los datos en una tabla.

Además se muestra como hacer para devolver solo las columnas que se desean pintar es decir, sin necesidad de estar creando varias entidades una para cada vista, al serializar indicamos que columnas deseamos enviar, reduciendo mas aún el tamaño del mensaje.

Sin dudas,  un video muy interesante para cualquier desarrollador que quiere optimizar el envío de datos del servidor al cliente, ya que no solo sirve para Web API, sino para cualquier método en MVC o WebForms.


Nota: A partir de mañana voy a publicar varios Demos relacionados a Performance, incluyendo el código de este último Demo de Web API con Serialización Personalizada (mejor que JSON).

lunes, 8 de diciembre de 2014

El Libro del Día: SQL Server 2012 T-SQL Recipes

El Libro del Día: 2014-12-08

Titulo: SQL Server 2012 T-SQL Recipes
Autor: Jason Brimhall, David Dye, Jonathan Gennick, 
           Andy Roberts, Wayne Sheffield
Editorial: Apress
Nro Paginas: 794

Capítulos:
Chapter 1: Getting Started with SELECT
Chapter 2: Elementary Programming
Chapter 3: NULLs and Other Pitfalls
Chapter 4: Querying from Multiple Tables
Chapter 5: Grouping and Summarizing
Chapter 6: Advanced Select Techniques
Chapter 7: Aggregations and Windowing
Chapter 8: Inserting, Updating, Deleting
Chapter 9: Working with Strings
Chapter 10: Working with Dates and Times
Chapter 11: Working with Numbers
Chapter 12: Transactions, Locking, Blocking, and Deadlocking
Chapter 13: Managing Tables
Chapter 14: Managing Views
Chapter 15: Managing Large Tables and Databases
Chapter 16: Managing Indexes
Chapter 17: Stored Procedures
Chapter 18: User-Defined Functions and Types
Chapter 19: Triggers
Chapter 20: Error Handling
Chapter 21: Query Performance Tuning
Chapter 22: Hints
Chapter 23: Index Tuning and Statistics
Chapter 24: XML
Chapter 25: Files, Filegroups, and Integrity
Chapter 26: Backup
Chapter 27: Recovery
Chapter 28: Principals and Users
Chapter 29: Securables, Permissions, and Auditing
Chapter 30: Objects and Dependencies

Descarga:
SQL_Server_2012_TSQL_Recipes

sábado, 8 de noviembre de 2014

El Libro del Día: Professional C# 2012 and .NET 4.5

El Libro del Día: 2014-11-08

Titulo: Professional C# 2012 and .NET 4.5
Autor: Christian Nagel, Bill Evjen, Jay Glynn, Karli Watson, Morgan Skinner
Editorial: Wrox
Nro Paginas: 1588

Capítulos:
PART I THE C# LANGUAGE
CHAPTER 1 .NET Architecture
CHAPTER 2 Core C#
CHAPTER 3 Objects and Types
CHAPTER 4 Inheritance
CHAPTER 5 Generics
CHAPTER 6 Arrays and Tuples
CHAPTER 7 Operators and Casts
CHAPTER 8 Delegates, Lambdas, and Events
CHAPTER 9 Strings and Regular Expressions
CHAPTER 10 Collections
CHAPTER 11 Language Integrated Query
CHAPTER 12 Dynamic Language Extensions
CHAPTER 13 Asynchronous Programming
CHAPTER 14 Memory Management and Pointers
CHAPTER 15 Reflection
CHAPTER 16 Errors and Exceptions
PART II VISUAL STUDIO
CHAPTER 17 Visual Studio 2012
CHAPTER 18 Deployment
PART III FOUNDATION
CHAPTER 19 Assemblies
CHAPTER 20 Diagnostics
CHAPTER 21 Tasks, Threads, and Synchronization
CHAPTER 22 Security
CHAPTER 23 Interop
CHAPTER 24 Manipulating Files and the Registry
CHAPTER 25 Transactions
CHAPTER 26 Networking
CHAPTER 27 Windows Services
CHAPTER 28 Localization
CHAPTER 29 Core XAML
CHAPTER 30 Managed Extensibility Framework
CHAPTER 31 Windows Runtime
PART IV DATA
CHAPTER 32 Core ADO.NET
CHAPTER 33 ADO.NET Entity Framework
CHAPTER 34 Manipulating XML
PART V PRESENTATION
CHAPTER 35 Core WPF
CHAPTER 36 Business Applications with WPF
CHAPTER 37 Creating Documents with WPF
CHAPTER 38 Windows Store Apps
CHAPTER 39 Core ASP.NET
CHAPTER 40 ASP.NET Web Forms
CHAPTER 41 ASP.NET MVC
CHAPTER 42 ASP.NET Dynamic Data
PART VI COMMUNICATION
CHAPTER 43 Windows Communication Foundation
CHAPTER 44 WCF Data Services
CHAPTER 45 Windows Workflow Foundation
CHAPTER 46 Peer-to-Peer Networking
CHAPTER 47 Message Queuing

Descarga:
Professional_C#2012_.NET4.5

sábado, 23 de agosto de 2014

El Libro del Día: jQuery Recipes

El Libro del Día: 2014-08-23

Titulo: jQuery Recipes
Autor: B.M. Harwani
Editorial: Apress
Nro Paginas: 455

Capítulos:
Chapter 1: jQuery Basics
Chapter 2: Arrays and Strings
Chapter 3: Event Handling
Chapter 4: Form Validation
Chapter 5: Page Navigation
Chapter 6: Visual Effects
Chapter 7: Dealing with Tables
Chapter 8: Ajax
Chapter 9: Using Plugins
Chapter 10: Using CSS

Descarga:
jQuery_Recipes

lunes, 4 de agosto de 2014

El Libro del Día: C# 5.0 All In One For Dummies

El Libro del Día: 2014-08-04

Titulo: C# 5.0 All In One For Dummies
Autor: Bill Sempf, Chuck Sphar, Stephen Randy Davis
Editorial: Wiley
Nro Paginas: 843

Capítulos:
Book I: The Basics of C# Programming
Chapter 1: Creating Your First C# Console Application
Chapter 2: Living with Variability - Declaring Value-Type Variables
Chapter 3: Pulling Strings
Chapter 4: Smooth Operators
Chapter 5: Getting into the Program Flow
Chapter 6: Lining Up Your Ducks with Collections
Chapter 7: Stepping through Collections
Chapter 8: Buying Generic
Chapter 9: Some Exceptional Exceptions
Book II: Object-Oriented C# Programming
Chapter 1: Object-Oriented Programming - What’s It All About?
Chapter 2: Showing Some Class
Chapter 3: We Have Our Methods
Chapter 4: Let Me Say This about this
Chapter 5: Holding a Class Responsible
Chapter 6: Inheritance: Is That All I Get?
Chapter 7: Poly-what-ism?
Chapter 8: Interfacing with the Interface
Chapter 9: Delegating Those Important Events
Chapter 10: Can I Use Your Namespace in the Library?
Chapter 11: Improving Productivity with Named and Optional Parameters
Book III: Designing for C#
Chapter 1: Writing Secure Code
Chapter 2: Accessing Data
Chapter 3: Fishing the FileStream
Chapter 4: Accessing the Internet
Chapter 5: Creating Images
Chapter 6: Programming Dynamically
Chapter 7: Helping Out with Interop
Book IV: A Tour of Visual Studio
Chapter 1: Getting Started with Visual Studio
Chapter 2: Using the Interface
Chapter 3: Customizing Visual Studio
Chapter 4: Transforming Text Templates
Book V: Windows Development with WPF
Chapter 1: Introducing WPF
Chapter 2: Understanding the Basics of WPF
Chapter 3: Data Binding in WPF
Chapter 4: Practical WPF
Book VI: Web Development with ASP.NET
Chapter 1: Looking at How ASP.NET Works with C#
Chapter 2: Building Web Applications
Chapter 3: Controlling Your Development Experience
Chapter 4: Leveraging the .NET Framework
Chapter 5: Digging into Web Construction
Book VII: Service-Oriented Development
Chapter 1: Getting Acquainted with Web Services
Chapter 2: Building Web Services with ASMX
Chapter 3: Building Web Services with WCF
Chapter 4: Building Web Services with REST

Descarga:
C#5.0_AllInOne_ForDummies