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

lunes, 20 de julio de 2015

Núcleo de .NET Framework y la CLR - Parte 2: Diagnóstico y Contratos de Código, Concurrencia y Sincronía, Entrada y Salida, Redes, Serialización, y Assemblies

Índice

0. Introducción
1. Diagnóstico y Contratos de Código
2. Concurrencia y Sincronía
3. Flujos de Entrada y Salida
4. Redes
5. Serialización
6. Assemblies, Reflection, y Atributos
7. Conclusiones
8. Glosario
9. Literatura & Enlaces

0. Introducción

En esta segunda parte de artículos .NET de introducción a .NET Framework describiremos grosso modo los siguientes temas de tratamiento detallado en futuras series: diagnóstico y contratos de código, concurrencia y sincronía, flujos de entrada y salida, redes, serialización, y assemblies, reflection, y atributos. El propósito de esta introducción es generalizar las series de artículos en los que estudiáremos en detalle los componentes del núcleo de Microsoft .NET Framework.

1. Diagnóstico y Contratos de Código

En este apartado nos enfocaremos en estudiar:
  • Cómo interactuar con otros procesos, 
  • Escritura en el log de eventos de Windows
  • Contadores de rendimiento para monitorización.
Para ello tenemos que estudiar el namespace System.Diagnostics.

2. Concurrencia y Sincronía

En las recetas multithreading C# hemos elaborado varias recetas para el trabajo de las construcciones de concurrencia, sincronía, y asincronía disponibles en los namespaces System.Threading y System.Threading.Tasks. Sin embargo, continuaremos nuestro estudio de alternativas de aprendizaje; esto con el propósito de profundizar y afianzar nuestro conocimiento y dominio de .NET.

3. Flujos de Entrada y Salida

.NET Framework cuenta con el modelo basado en flujos de entrada y salida de bajo nivel [1]. En la serie de artículos .NET Framework describiremos y pondremos en práctica temas como:
  • Lectura y escritura sobre archivos y conexiones de red, 
  • Adición de compresión y encriptación en flujos de entrada y salida.
Nuestro estudio también se enfocará en la arquitectura de flujos de .NET:
  • Soporte para el trabajo de archivos y directorios, 
  • Compresión, 
  • Almacenamiento aislado, 
  • Pipes
  • Archivos asignados en memoria
Los namespaces a estudiar: 
  • System.IO
  • Windows.Storage.

4. Redes

Nos detendremos en el estudio de acceso a través protocolos como: 
  • HTTP
  • FTP
  • TCP/IP
  • SMTP.
Para ellos tendremos que estudiar los elementos de programa disponibles en el namespace System.Net. Además de:
  • System.Http: namespace con clases para el manejo de operaciones con el protocolo HTTP
  • System.Net.Mail: namespace que contiene clases que permiten el envío de correo electrónico a través del protocolo SMTP
  • System.Net.Sockets: namespace con tipos para la gestión de Windows Sockets (Winsock).

5. Serialización

Para aplicaciones distribuidas Microsoft .NET Framework ofrece las siguientes tecnologías:
  • Windows Communication Foundation (WCF), 
  • Web Services, e 
  • Interacción remota (remoting)
Para estas tecnologías es preciso estudiar cómo guardar y restaurar objetos desde y hacia su representación binaria o textual. Por lo tanto, es preciso explorar los namespaces:
  • System.Runtime.Serialization, y 
  • System.Xml.Serialization

6. Assemblies, Reflection, y Atributos

En la tercera serie de recetas C# hemos descrito varias de las construcciones para el trabajo con assemblies, reflection, y atributos. Evidentemente, crearemos más contenido para comprender detalles particulares sobre estos tres temas. Estudiáremos con más cuidado y atención los namespaces:
  • System
  • System.Reflection
  • System.Reflection.Emit.

7. Conclusiones

Realizamos una descripción generalizada de los temas de futuras series de artículos .NET Framework. Muchos de los temas descritos los hemos tratado en artículos y recetas, sin embargo queremos seguir comprendiendo más fondo las particularidades y sutilezas detrás de .NET.


Con el siguiente artículo finalizamos esta serie de introducción .NET Framework y la descripción de los componentes de núcleo que lo integran.

8. Glosario

  • Asincronía
  • Assembly
  • Atributos
  • Concurrencia
  • Log
  • Namespace
  • Protocolo
  • Windows
  • Winsockets

9. Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Recetas Multithreading en C# - http://ortizol.blogspot.com/search/label/Multithreading
[3]: Recetas C# Assemblies, Reflection, y Atributos - http://ortizol.blogspot.com/search/label/AppDomain


V

martes, 7 de julio de 2015

Enlace Dinámico en C# - Parte 4: Expresiones Dinámicas

Índice

0. Introducción
1. Expresiones Dinámicas
1.1 Retorno void
1.2 Operandos dinámicos
1.3 Casos excepciones en expresiones dinámicas
2. Llamadas Dinámicas sin Receptores Dinámicos
3. Conclusiones
4. Glosario
5. Literatura & Enlaces

0. Introducción

En esta cuarta entrega de la serie de artículos de Enlace Dinámico en C# veremos cómo los elementos de programa (i.e., campos, propiedades, métodos, eventos, constructores, indezadores, operadores) y operaciones (e.g., conversión) pueden ser invocados de forma dinámica. A esto le sumaremos la exploración de excepciones en donde expresión dinámica retorna una expresión estática. Luego exploraremos el uso de expresiones sin receptores dinámicos.
  1. Introducción al Enlace Dinámico, Enlace estático vs enlace dinámico, RuntimeBinderException
  2. Enlace Personalizado, Enlace de Lenguaje
  3. La Palabra Clave dynamic, Conversiones, Diferencia entre var y dynamic
  4. Expresiones Dinámicas, Expresiones Dinámicas sin Receptores Dinámicos
  5. Tipos Estáticos en Expresiones Dinámicas, Funciones Non-Invocables

1. Expresiones Dinámicas

Los elementos de programa que son posibles construir con el lenguaje de programación C# permiten ser invocados de forma dinámica. Entre ellos tenemos:
  • Campos
  • Constructores
  • Eventos
  • Indexadores
  • Métodos
  • Operadores
  • Propiedades
Además, expresiones que involucran la conversión entre tipos, también están permitidos en invocaciones dinámicas.

1.1 Retorno void

En [1] nos dicen que las expresiones dinámicas que retornan void no pueden formar parte de una asignación. Esto está prohíbido: en tiempo de ejecución se genera la excepción RuntimeBinderException (Enlace Dinámico en C# - Parte 1: Introducción). Por ejemplo si tratamos de hacer algo como esto:

dynamic lista = new List();
var resultado = lista.Add(new Libro("Los hermanos Karámazov", "Fyódor Dostoyevski");

En tiempo de ejecución se lanzará la excepción RuntimeBinderException debido a que el método Add de List retorna void. Recordemos que lo mismo sucede en tiempo de compilación cuando intentamos hacer algo como esto:

FileInfo archivo = new FileInfo("LosHermanosKaramov.mobi");
var resultado = archivo.Refresh();

La implementación del método Refresh [3] de la clase FileInfo retorna void. En tiempo de compilación se generá el error CS0815 [6]:

Cannot assign void to an implicitly-typed local variable

1.2 Operandos dinámicos

Una expresión que incluya uno o más operandos dinámicos es generalmente dinámica. Esto se debe al argumento dado en [1]:
"...since the effect of absent type information is cascading."
Para demostrarlo, recurramos a este fragmento de código:

dynamic x = 2;
var resultado = x * 3;

Aquí, cuando se efectúe la operación del lado derecho

x * 3

El tipo estático reconocido por el compilador para resultado será dynamic.

1.3 Casos excepcionales en expresiones dinámicas

1.3.1 Casting

Para las conversiones explícitas, el compilador asignará un tipo estático. Por ejemplo:

dynamic x = 5;
var y = (int) x;

La variable definida como var será estáticamente de tipo int.

1.3.2 Instanciación

Debemos tener presente que la invocación de un constructor de un tipo genera expresiones estáticas. E inclusive cuando uno o más argumentos sean de tipo dinámico [1]:

dynamic cantidad = 19;
var libro = new Libro("Los hermanos Karámazov", "Fyódor Dostoyevski", cantidad);

En esta situación, estáticamente, el compilador reconocerá libro (var) como de tipo Libro.

2. Llamadas Dinámicas sin Receptores Dinámicos

Como receptor podemos referirnos a un objeto capaz de infocar una función dinámica. Por ejemplo:

dynamic x = ...;
x.MetodoDinamico();

En este caso x es el receptor de una llamada a una función dinámica: MetodoDinamico.

Sin embargo, hay excepciones en donde es posible invocar funciones (en término general) estáticas con argumentos dinámicos; por ejemplo [1]:
  • Métodos estáticos
  • Constructores de instancia
  • Métodos de instancia invocados desde un receptor identificado con un tipo estático
Para comprender mejor este concepto podemos adaptar el ejemplo que se encuentra en [1]:

Ejemplo de uso:


Notemos que los argumentos de las llamadas a los métodos sobrecargados MostrarConsola (líneas 13 y 14) reciben como argumento valores de tipo dynamic. Debido a la ausencia de receptores dinámicos en tiempo de compilación el compilador es capaz estáticamente de resolver las llamadas a los métodos sobrecargados MostrarEnConsola.


Por otra parte, debido a que el chequeo se realiza en tiempo de compilación en un programa como el siguiente se generan errores compilación:

Ejemplo de uso:

Archivo C# ResolucionEstatica.cs [Enlace alternativo]:



Notemos que a pesar de que las llamadas a:
  • MostrarEnConsola, y 
  • MostrarEnDialogo
involucran tipos dinámicos, el compilador es capaz de resolver estáticamente los errores de compilación que se pudieran generar. En este caso lo logra debido a que las funciones no tienen especificado un receptor dinámico.

3. Conclusiones

En este artículo C# hemos explorado los básicos para comprender las sutilezas en la invocación de miembros con expresiones dinámicas. La promoción a tipo dinámico el resultado de la evaluación de expresiones que involucran tipos dinámicos. Estamos advertidos de la restricción de intento erróneo de asignación de retorno void de una expresión dinámica (e.g., list.Add(...)). Al final vimos cómo en casos excepcionales el compilador es capaz de resolver estáticamente las invocaciones a expresiones que no involucran un receptor dinámico.


La quinta y última parte de esta serie de artículos de Enlace Dinámico lo dedicaremos principalmente a estos temas:
  • Tipos estáticos en expresiones dinámicas, 
  • Funciones no-invocables, y 
  • Representación de dinámicos en tiempo de ejecución.

4. Glosario

  • Expresión dinámica
  • Expresión estática
  • Función
  • Invocación
  • Miembro
  • Receptor
  • Resolución dinámica
  • Resolución estática

5. Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Enlace Dinámico en C#: Introducción - http://ortizol.blogspot.com/2015/07/enlace-dinamico-en-csharp-parte-1.html
[3]: FileSystemInfo.Refresh Method (System.IO) - https://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.refresh(v=vs.110).aspx
[4]: Compiler Error CS0815 - https://msdn.microsoft.com/en-us/library/bb384140(v=vs.90).aspx


J

lunes, 6 de julio de 2015

Enlace Dinámico en C# - Parte 3: La Palabra Clave Dynamic, Conversiones, y var vs. dynamic

Índice

0. Introducción
1. La Palabra Clave dynamic
2. Conversiones Dinámicas
3. var vs. dynamic
3.1 Diferencia fundamental
3.2 Tiempo de compilación vs. tiempo de ejecución
3.3 Conversiones
4. Conclusiones
5. Glosario
6. Literatura & Enlaces

0. Introducción

Esta tercera parte de la serie de artículos de Enlace Dinámico estará dedicada a tratar la palabra clave dynamic, conversiones entre dynamic y otros tipos de datos, y haremos una comparación de uso de var (deducción de tipos en tiempo de compilación) y dynamic.
  1. Introducción al Enlace Dinámico, Enlace estático vs enlace dinámico, RuntimeBinderException
  2. Enlace Personalizado, Enlace de Lenguaje
  3. La Palabra Clave dynamic, Conversiones, Diferencia entre var y dynamic
  4. Expresiones Dinámicas, Expresiones Dinámicas sin Receptores Dinámicos
  5. Tipos Estáticos en Expresiones Dinámicas, Funciones Non-Invocables

1. La Palabra Clave dynamic

Desde la versión 4.0 de Microsoft .NET Framework en C# podemos utilizar la palabra clave dynamic [2] para la resolución de miembros de tipos en tiempo de ejecución. En tiempo de compilación la comprobación de tipos, castingboxing y unboxing, y demás operaciones de chequeo son descartados por el compilador.

En este ejemplo podemos encontrar la diferencia entre la comprobación en tiempo de compilación y en tiempo de ejecución.

Archivo C# PruebaDynamicObject.cs [Enlace alternativo]:


En la línea 10 declaramos una variable de dynamic -dyn-, y la inicializamos con la literal entera 1; en la siguiente línea una instancia de object -obj-, con el valor entero 1 (boxing). Más adelante sobre la línea 13 sumamos 3 al valor 1 que tiene encapsulado el tipo dynamic (línea 10).

Continuando, si intentamos hacerlo mismo con object, es decir 

obj = ((object)obj) + 3;


el compilador de C# generará el error CS0019 [3] debido a que no es posible aplicar el operador + sobre un tipo object y una literal entera (en su lugar, era necesario hacer casting((object)obj) + 3). Notemos que esto ha ocurrido en tiempo de compilación, y por supuesto, nos genera una ventaja significativa sobre la comprobación de tipos en tiempo de ejecución. Demostrémolo a través del intento de invocar un miembro no definido sobre la variable dynamic -dyn-:

dyn.MetodoInexistente ()

La compilación del programa en el archivo de código fuente PruebaDynamicObject.cs no generará ningún error en tiempo de compilación, sin embargo, cuando intentemos ejecutar el assembly:

.\PruebaDynamicObject.exe

obtendremos el siguiente mensaje de error:

Intento de invocar método inexistente en una variable dynamic
Figura 1. Intento de invocar método inexistente en una variable dynamic.
En el mensaje de error que aparece en la Figura 1 se informa que ha ocurrido la excepción RuntimeBinderException (N:Microsoft.CSharp.RuntimeBinder[6] que se traduce en el intento de enlazar (binding) miembros de un tipo inexistentes en tiempo de ejecución.

Antes de finalizar, sobre el artículo en DotNetPerls [2, 7] nos advierten sobre el uso de dynamic:
Dynamic is advanced functionality. It can be useful. But usually it should be avoided. It erases many benefits of the C# language.
Además:
The dynamic keyword influences compilation. A dynamic variable, parameter or field can have any type. Its type can change during runtime. The downside is that performance suffers and you lose compile-time checking.

2. Conversiones Dinámicas

Las variables declaradas con dynamic tienen la capacidad de efectuar conversiones implícitas. Veamos este fragmento de código:

int entero32Bits = 7;
dynamic dyn = entero;
long entero64Bits = dyn; // Conversión implícita: no se requiere casing


En la tercera línea la conversión implícita del objeto dynamic a long está permitada debido a que int  es implícitamente convertible a long. En general, los tipos estáticos de destino deben soportar la conversión del tipo implícito dinámico de origen.


En contraste, cuando intentamos

int entero32Bits = 7;
dynamic dyn = entero;
short entero16Bits = dyn; // Se lanza la excepción RuntimeBinderException


se lanza la excepción RuntimeBinderException (Enlace Dinámico en C# - Parte 1: Introducción) debido que el tipo estático de destino no permite conversión implícita entre int a short.

3. var vs. dynamic

3.1 Diferencia fundamental

Podemos resumir la diferencia de var y dynamic como en [1]:
var says, "Let the compiler figure out the type."
dynamic says, "Let the runtime figure out the type."

3.2 Tiempo compilación vs. tiempo de ejecución

A nivel de código podemos diferenciar estas dos construcciones así:

dynamic x = "xCSw"; // Tipo estático: dynamic; Tipo en ejecución: string
var y = "xCSw"; // Tipo estático: string; Tipo en ejecución: string
int i = x; // Error en tiempo de ejecución
int j = y; // Error en tiempo de compilación

3.3 Conversiones

En tiempo de compilación puede establecerse el tipo de una variable declarada con var en dynamic:

dynamic x = "xCSw";
var y = x; // Tipo estático de la variable y dynamic
int z = y; // Error en tiempo de ejecución

La segunda línea de código es permitida por el compilador ya que la conversión de un tipo dynamic a var está permitida: el compilador asignara a y el tipo dynamic. En cuanto a la tercera línea, la conversión falla: no está permitida la conversión de string a int.

[Nota: Para conocer más acerca de var recomiendo la lectura de este artículo var - Variables Locales de Tipo Deducido Implícitamente en C#.]

4. Conclusiones

Estudiamos varios aspectos importantes de la palabra clave (o reservada) dynamic: la disposición de esta palabra en .NET para agregar capacidades dinámicas a nuestro código, por ejemplo, la agregación de miembros en tiempo de ejecución (demostrado en la segunda parte de esta serie de Enlace Dinámico), las conversiones implícitas permitidas, y la comparación entre var y dynamic.

5. Glosario

  • .NET
  • Conversión implícita
  • dynamic
  • Tiempo de compilación
  • Tiempo de ejecución
  • var

6. Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Using Type dynamic (C# Programming Guide) - https://msdn.microsoft.com/en-us/library/dd264736.aspx
[3]: Compiler Error CS0019 - http://msdn.microsoft.com/en-us/library/a63h61ky.aspx
[4]: Enlace Dinámico en C# - Parte 1: Introducción - http://ortizol.blogspot.com/2015/07/enlace-dinamico-en-csharp-parte-1.html
[5]: Enlace Dinámico en C# - Parte 2: Enlace de Lenguaje y Personalizado - http://ortizol.blogspot.com/2015/07/enlace-dinamico-en-csharp-parte-2-enlace-de-lenguaje-y-personalizado.html
[6]: var - Variables Locales de Tipo Deducido Implícitamente en C# - http://ortizol.blogspot.com/2013/09/var-variables-locales-de-tipo-deducido.html


J

sábado, 4 de julio de 2015

Receta C# No. 4-17: Garantizar la Ejecución de una Sola Instancia de una Aplicación

Índice

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
4. Práctica: Código C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

Algunas aplicaciones que creemos sólo requerirán una sola instancia en ejecución. Este tipo requerimiento puede generarse en una aplicación de cómputo intensivo en donde sóla una instancia por estación de trabajo está permitido debido a los límites del hardware, por ejemplo. Veremos que a nivel programático podemos aplicar esta restricción a través de la técnica de exclusión mutúa. Para ello, como ya veremos, el lenguaje de programación C# provee la clase System.Threading.Mutex.

1. Problema

Debemos asegurarnos que un usuario de un sistema operacional sólo pueda ejecutar una única instancia de una aplicación. Esto con el propósito de hacer uso eficiente de los recursos de cómputo locales y el acceso a datos para una cuenta de usuario.

2. Solución

C# cuenta con la construcción Mutex (namespace System.Threading) para este cometido. En esencia, a través del mecanismo de exclusión mutua que provee Mutex, es posible controlar la adquisición del espacio de ejecución por parte de una única instancia.

3. Discusión de la Solución

Para no extendernos en esta sección recomiendo al lector dirigirse a la receta Receta C# No. 4-9: Sincronización de Múltiples Threads usando Mutex y leer cuidadosamente los ejemplos de uso de la clase Mutex [3].

4. Práctica: Código Fuente C#

Creamos un ejemplo que haga uso de la Mutex para controlar la ejecución de una única instancia llamada UnicaInstancia. Cualquier intento de ejecución del assembly ejecutable mostrará al usuario un mensaje de advertencia que una instancia ya se halla en ejecución y enseguida finalizará.


En las líneas 8-40 se efectúan las siguientes operaciones:
  • Línea 12: declaración variable booleana para controlar si un objeto Mutex tiene control exclusivo sobre la ejecución de una aplicación.
  • Línea 16: Creación de una instancia de Mutex con using con la firma Mutex(Boolean, String, Boolean) [4]. El primer argumento del constructor indica que el thread inicial toma control exclusivo sobre la aplicación con nombre UnicaAplicacion.

    El tercer argumento controla si ya existe una instancia de esta aplicación en ejecución.
  • Línea 19: Comprueba si la aplicación ya se haya en ejecución, en caso de ser así se mostrará el mensaje de la línea 21. Para finalizar la aplicación es necesario presionar Enter, esto permitirá que otra instancia se ejecute y tome el control a través de un objeto Mutex.
  • Línea 29: Muestra mensaje en caso de que la aplicación ya se encuentre en ejecución.

Compilación:


  1. csc /target:exe UnicaInstanciaAplicacion.cs

Ejecución assembly:


  1. .\UnicaInstanciaAplicacion.exe

> Prueba de ejecución (local):
Ejecución assembly UnicaInstanciaAplicacion.exe
Figura 1. Ejecución assembly UnicaInstanciaAplicacion.exe.

5. Conclusiones

Esta receta nos ha mostrado los esenciales para restringir la ejecución de una aplicación por una sola instancia. La solución fue usar la versión sobrecargada del constructor de Mutex con la firma Mutex(Boolean, String, Boolean).


Con esta receta terminamos la serie de Recetas C# dedicadas a threads, processo, y sincronización. La siguiente serie estará centrada en archivos, directorios y entrada/salida.

6. Glosario

  • Exclusión mutua
  • Instancia
  • Mutex
  • Thread

7. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: Receta C# No. 4-9: Sincronización de Múltiples Threads usando Mutex - http://ortizol.blogspot.com/2014/07/receta-csharp-no-4-9-sincronizacion-de-multiples-threads-usando-mutex.html
[3]: Mutex Class (System.Threading) - https://msdn.microsoft.com/en-us/library/vstudio/system.threading.mutex(v=vs.100).aspx
[4]: Mutex Constructor (Boolean, String, Boolean) (System.Threading) - https://msdn.microsoft.com/en-us/library/vstudio/bwe34f1k(v=vs.100).aspx


J