Download accepts a wait handle (as an argument) and causes the calling

Document related concepts
no text concepts found
Transcript
Lenguaje C#
Enfoque Marco Tecnológico en el que se sitúa
Enfoque Programación Paralela
Universidad Católica De Santa María
Ingeniería de sistemas
Autores:
Noé Omar Alcázar Salas [email protected] 1999800051
Armando Lazarte Aranaga
Talía de la Cruz Hualpa
Edgardo Ponce Escobedo
Abstract
This paper was made with purpose of explaining where does the C# programming language,
takes place in the technological world of programming languages and the future of computing
science, explaining why of it’s creation and why it’s use gonna be maybe the standard language
used for internet programming & development.
We explain too the characteristics of C# oriented to parallel programming, like creation and
management of threads, also the classes that allow us to perform good synchronization in
multithreading programs.
1. Introducción a C#
Origen y necesidad de un nuevo lenguaje
C# (leído en inglés "C Sharp" y en español "C Almohadilla") es el nuevo lenguaje de propósito
general diseñado por Microsoft para su plataforma .NET. Sus principales creadores son Scott
Wiltamuth y Anders Hejlsberg, éste último también conocido por haber sido el diseñador del
lenguaje Turbo Pascal y la herramienta RAD Delphi.
Aunque es posible escribir código para la plataforma .NET en muchos otros lenguajes, C# es el
único que ha sido diseñado específicamente para ser utilizado en ella, por lo que programarla
usando C# es mucho más sencillo e intuitivo que hacerlo con cualquiera de los otros lenguajes ya
que C# carece de elementos heredados innecesarios en .NET. Por esta razón, se suele decir que
C# es el lenguaje nativo de .NET
La sintaxis y estructuración de C# es muy similar a la C++, ya que la intención de Microsoft con
C# es facilitar la migración de códigos escritos en estos lenguajes a C# y facilitar su aprendizaje
1
a los desarrolladores habituados a ellos. Sin embargo, su sencillez y el alto nivel de
productividad son equiparables a los de Visual Basic.
Un lenguaje que hubiese sido ideal utilizar para estos menesteres es Java, pero debido a
problemas con la empresa creadora del mismo -Sun-, Microsoft ha tenido que desarrollar un
nuevo lenguaje que añadiese a las ya probadas virtudes de Java las modificaciones que Microsoft
tenía pensado añadirle para mejorarlo aún más y hacerlo un lenguaje orientado al desarrollo de
componentes.
En resumen, C# es un lenguaje de programación que toma las mejores características de
lenguajes preexistentes como Visual Basic, Java o C++ y las combina en uno solo. El hecho de
ser relativamente reciente no implica que sea inmaduro, pues Microsoft ha escrito la mayor parte
de la BCL usándolo, por lo que su compilador es el más depurado y optimizado de los incluidos
en el .NET Framework SDK
2. Lenguaje C# y el Marco Tecnológico en el que se sitúa
Para ello dividiremos esta sección en dos subsecciones: la primera de ellas dedicadas a .NET y la
segunda de ellas dedicada a C#. Es importante notar que para entender en profundidad las
características de C# es imprescindible estudiar antes .NET por lo que será la primera sección
que tratemos.
2.1 Microsoft .NET
NET no es más que la nueva generación de productos orientados al mundo de Internet y al de los
dispositivos móviles que la multinacional norteamericana Microsoft presentó el pasado 22 de
Julio en la conferencia PDC(Professional Developers Conference) celebrada en Orlando
(Florida). .NET es anunciado por Microsoft como una nueva era en el desarrollo de aplicaciones
tanto en entorno Windows, como en el resto de entornos que la soporten en un futuro, y la
presentan como el estándar para Internet y todos los dispositivos que a ella se conecten.
2.2 Características de Microsoft .NET
Utilización de XML
La información procedente de distintos servicios suele tener formatos totalmente distintos de
forma que el intercambio de información entre ellos supone un serio problema. Para salvar este
contratiempo en .NET se utiliza el lenguaje XML(Extensible Markup Language). Toda la
información que tenga que fluir de un servicio a otro será descrita con XML con el fin de
establecer la correspondencia entre el formato de la información de cada servicio y los demás.
Además, la comunicación entre servicios se realizarán utilizando el protocolo SOAP (Simple
Object Access Protocol) que, como es de esperar, también está basado en XML y que permite
invocar métodos, servicios, componentes y objetos de otros servicios remotos.
Con este objetivo Microsoft ha construido una nueva herramienta para el desarrollo rápido de
aplicaciones y servicios web llamada Visual Studio .NET que aún esta en versión beta. En la esta
nueva versión del Visual Studio se incluyen los lenguajes Visual Basic, JScript, C++ y un nuevo
lenguaje cuyo objetivo es sustituir a Java llamado C#, además, hay trabajando una conjunto de
universidades y empresas privadas en incluir en .NET nuevos lenguajes de programación entre
2
los que se encuentran APL, CAML, Cobol, Haskell, Mercury, Ml, Oberon, Oz, Pascal, Perl,
Python, Scheme, Smalltalk, e incluso JAVA en un proyecto liderado por la empresa Rational.
Lo más atractivo quizás de este nuevo entorno de desarrollo es la capacidad de construir por
ejemplo, parte de nuestra aplicación en Visual Basic y el resto en C++, C#, o incluso aprovechar
una aplicación antigua sin tener que preocuparnos por la integración, con lo que facilitamos en
gran medida la reutilización de código
Para conseguir la integración, Microsoft se ha basado en la misma idea que utiliza Java para
conseguir la portabilidad. La idea es construir una máquina virtual de forma que todo el código
que escribamos se traduzca a un lenguaje intermedio común para todos los lenguajes, en este
caso MSIL (Microsoft Intermediate Language) y en el caso de Java los bytecodes, que será el
que la máquina virtual ejecutará. El principal problemas de Java es la eficiencia y este está
derivado sin duda de la utilización de una máquina virtual. En este sentido Microsoft anuncia que
la perdida de eficiencia en .NET va a ser sólo de un 10% aproximadamente, pero aún es pronto
para hablar de eficiencia y tendremos que esperar a la versión definitiva del Visual Studio .NET
para observar estos resultados.
Para realizar esta afirmación, Microsoft se apoya en varios aspectos:
 1. Por un lado, MSIL es de más alto nivel que otros lenguajes máquinas: trata
directamente con objetos y tiene instrucciones para crearlos e inicializarlos directamente,
puede llamar a métodos virtuales sobre objetos y manipular elementos de tablas
directamente. Incluso tiene instrucciones para el manejo de excepciones. De forma que la
máquina virtual debe ser más eficiente que la JVM.
 2. Por otro lado, los compiladores utilizados son JIT (Just in TIme) que producen, o
producirán, código nativo optimizado para el microprocesador que estemos usando, no
compatible con toda la familia x86 como hacen otros JITs, de modo que al usar toda las
capacidades de nuestro micro (registros, instrucciones propias del micro que usemos,
3
etc.) hacemos que el código se ejecute más rápido. En .NET hay tres tipos de
compiladores JIT, los dos primeros nos permiten generar código nativo sin optimizar y
optimizado. Estos JITs compilan a código nativo bajo demanda y una vez una parte está
ya compilada, se guarda para utilizarla posteriormente evitando tener que volver a
traducirla. El tercer tipo es un compilador de los de toda la vida que compila a nativo
todo el código y guarda el resultado en disco.
2.3 El Núcleo de .NET. El Common Languaje Runtime (CLR)
Para construir una máquina virtual común a todos los lenguajes primero hay que definir una serie
de características comunes a todos ellos. Este conjunto de características comunes se engloban en
el llamado Common Languaje Runtime(CLR). A continuación veremos algunas de las
características que contempla el CLR:
 Es Orientado a objetos, no podría ser de otro modo. Soporta herencia (simple),
polimorfismo, manejo de excepciones, etc.
 Posee un conjunto de tipos común estandarizado, el "Common Type System" (CTS). Esto
elimina la ambigüedad en el sentido de que un entero se represente con 16 bits o 32 o que
se soporte o no la herencia múltiple.
 Soporta metainformación para todos los tipos en tiempo de ejecución.
 Posee un conjunto de clases pertenecientes a .NET que encapsulan la mayoría de la
funcionalidad del API win32 y otras tecnologías, como XML, etc.
 Proporciona opciones avanzadas para depurar aplicaciones. Proporciona un depurador
que actúa entre lenguajes distintos, que nos permite recorrer la pila, etc.
 Proporciona ejecución virtual de código y manejo de memoria automático.
 Posee un recolector de basura.
 Proporciona traductores de lenguaje intermedio a código nativo.
 Y tiene un modelo de seguridad declarativo.
El código que cumple con las restricciones del CLR se llama código "manejado", "managed
code" en inglés. Todos los lenguajes que incluye .NET producen código manejado menos el C++
que posee características que se salen de las especificaciones, por ejemplo, el C++ permite la
herencia múltiple que en el CLR no se permite. Para solucionar este problema se utilizan las
llamadas extensiones de manejo (Managed Extension) que hacen que el código que escribamos
en C++ se ajuste a CLR.
Al tener un runtime común para todos los lenguajes, si escribimos dos clases con la misma
funcionalidad, una de ellas codificada en Visual Basic y la otra codificada en C#, su traducción a
lenguaje intermedio, es decir, a MSIL, será exactamente la misma.
3. ¿Donde Ingresa C#?
Java se ha consolidado durante los últimos años como uno de los lenguajes más populares en el
ámbito de Internet puesto que proporciona a los programadores la flexibilidad, la potencia y la
portabilidad que las aplicaciones web precisan. Pero Microsoft no parecía nada contenta al ver
que un lenguaje de la competencia triunfaba en un terreno en el que mantiene algunas de sus más
encarnizadas batallas legales y tecnológicas. Por esta razón arremete ahora contra Sun con una
nueva forma de ver la programación, .NET, en la que se incluye su candidato para sustituir a
Java, C#.
4
C y C++ son dos de los lenguajes más utilizados en el campo de la ingeniería y la programación
de sistemas. Se cuentan por millones los programadores expertos en ellos y no son menos los que
de forma tradicional han venido resistiéndose a aprender Java. La principal razón es que C o C++
proporcionan el nivel de abstracción preciso para embarcarse en la construcción de una
aplicación compleja, pero, al mismo tiempo, ofrecen mecanismos de bajo nivel que permiten a
los programadores hacer uso de las características más avanzadas de las plataformas sobre las
que se ejecutan sus programas. Por el contrario, Java está lastrado por su compromiso con la
portabilidad y es inherentemente ineficiente.
Microsoft se ha dado cuenta que en ese grupo de programadores podría encontrar una nueva
línea de expansión para sus productos y es en este sentido en el que aparece C# que combina
algunas de las características más avanzadas de Java con algunas de las más potentes de C y
C++. La idea es convertirlo en el nuevo lenguaje de Internet y, por supuesto, en el lenguaje
nativo para acceder a todos los servicios que en el futuro brindará .NET.
El nuevo lenguaje de Microsoft, al igual que c y C++, permite programar fácilmente a bajo nivel.
Gracias a esto, acceder a las características avanzadas de la plataforma sobre la que trabajamos,
crear código muy eficiente en aquellos puntos de la aplicación que son críticos y acceder a las
interfaces de programación de aplicaciones (APIs) existentes es perfectamente posible.
En concreto, C# está especialmente preparado para acceder al API de Windows y los objetos
COM+ y DLL del sistema, por lo que las aplicaciones escritas en este lenguaje podrán
aprovechar todas las características de este popular sistema operativo y de .NET.
Muchos dicen que si Java se puede considerar un C++ mejorado en cuestiones de seguridad y
portabilidad, C# debe entenderse como un Java mejorado en todos los sentidos: desde la
eficiencia hasta la facilidad de integración con aplicaciones tan habituales como Microsoft Office
o Corel Draw.
3.1 Java y C#
Lo cierto es que cualquier programador podría confundir perfectamente un programa sencillo en
C# y creer que se trata de Java, puesto que en ambos se escribe de una forma muy parecida. No
obstante, las diferencias son muchas y sus ventajas frente a Java se hacen patentes en el
momento en que profundizamos un poco más.
Los dos lenguajes son muy parecidos ya que ambos tienen recolector de basura, ambos son
orientados a objetos, ninguno soporta la herencia múltiple, ambos tienen manejo de excepciones,
etc. Pero como ya hemos dicho, C# añade algunas características bastante atractivas, como por
ejemplo hacer el acceso objetos COM+ y a las DLLs totalmente transparente, ya que se asocia un
objeto COM+ a una clase y a partir de ese momento los objetos de esa clase podrán hacer
llamadas a los métodos del componente como lo haría cualquier otro objeto.
Además, la sintaxis de C# es bastante parecida a Java, por ejemplo, los nombres de las librerías
que nos proporcionan son muy parecidos, de forma que la traducción de un programa "sencillo"
implementado en Java a C# es casi directa.
3.2 Características de C#
Con la idea de que los programadores más experimentados puedan obtener una visión general del
lenguaje, a continuación se recoge de manera resumida las principales características de C#
Alguna de las características aquí señaladas no son exactamente propias del lenguaje sino de la
5
plataforma .NET en general. Sin embargo, también se comentan aquí también en tanto que tienen
repercusión directa en el lenguaje, aunque se indicará explícitamente cuáles son este tipo de
características cada vez que se toquen:
 Sencillez: C# elimina muchos elementos que otros lenguajes incluyen y que son
innecesarios en .NET. Por ejemplo:
 El código escrito en C# es autocontenido, lo que significa que no necesita de
ficheros adicionales al propio fuente tales como ficheros de cabecera o ficheros
IDL
 El tamaño de los tipos de datos básicos es fijo e independiente del compilador,
sistema operativo o máquina para quienes se compile (no como en C++), lo que
facilita la portabilidad del código.
 No se incluyen elementos poco útiles de lenguajes como C++ tales como macros,
herencia múltiple o la necesidad de un operador diferente del punto (.) acceder a
miembros de espacios de nombres (::)
 Modernidad: C# incorpora en el propio lenguaje elementos que a lo largo de los años ha
ido demostrándose son muy útiles para el desarrollo de aplicaciones y que en otros
lenguajes como Java o C++ hay que simular, como un tipo básico decimal que permita
realizar operaciones de alta precisión con reales de 128 bits (muy útil en el mundo
financiero), la inclusión de una instrucción foreach que permita recorrer colecciones con
facilidad y es ampliable a tipos definidos por el usuario, la inclusión de un tipo básico
string para representar cadenas o la distinción de un tipo bool específico para representar
valores lógicos.
 Orientación a objetos: Como todo lenguaje de programación de propósito general
actual, C# es un lenguaje orientado a objetos, aunque eso es más bien una característica
del CTS que de C#. Una diferencia de este enfoque orientado a objetos respecto al de
otros lenguajes como C++ es que el de C# es más puro en tanto que no admiten ni
funciones ni variables globales sino que todo el código y datos han de definirse dentro de
definiciones de tipos de datos, lo que reduce problemas por conflictos de nombres y
facilita la legibilidad del código.
C# soporta todas las características propias del paradigma de programación orientada a
objetos: encapsulación, herencia y polimorfismo.
En lo referente a la encapsulación es importante señalar que aparte de los típicos
modificadores public, private y protected, C# añade un cuarto modificador llamado
internal, que puede combinarse con protected e indica que al elemento a cuya definición
precede sólo puede accederse desde su mismo ensamblado.
Respecto a la herencia -a diferencia de C++ y al igual que Java- C# sólo admite herencia
simple de clases ya que la múltiple provoca más quebraderos de cabeza que facilidades y
en la mayoría de los casos su utilidad puede ser simulada con facilidad mediante herencia
múltiple de interfaces. De todos modos, esto vuelve a ser más bien una característica
propia del CTS que de C#.
Por otro lado y a diferencia de Java, en C# se ha optado por hacer que todos los métodos
sean por defecto sellados y que los redefinibles hayan de marcarse con el modificador
virtual (como en C++), lo que permite evitar errores derivados de redefiniciones
accidentales. Además, un efecto secundario de esto es que las llamadas a los métodos
serán más eficientes por defecto al no tenerse que buscar en la tabla de funciones
6



virtuales la implementación de los mismos a la que se ha de llamar. Otro efecto
secundario es que permite que las llamadas a los métodos virtuales se puedan hacer más
eficientemente al contribuir a que el tamaño de dicha tabla se reduzca.
Orientación a componentes: La propia sintaxis de C# incluye elementos propios del
diseño de componentes que otros lenguajes tienen que simular mediante construcciones
más o menos complejas. Es decir, la sintaxis de C# permite definir cómodamente
propiedades (similares a campos de acceso controlado), eventos (asociación controlada
de funciones de respuesta a notificaciones) o atributos (información sobre un tipo o sus
miembros)
Gestión automática de memoria: Como ya se comentó, todo lenguaje de .NET tiene a
su disposición el recolector de basura del CLR. Esto tiene el efecto en el lenguaje de que
no es necesario incluir instrucciones de destrucción de objetos. Sin embargo, dado que la
destrucción de los objetos a través del recolector de basura es indeterminista y sólo se
realiza cuando éste se active -ya sea por falta de memoria, finalización de la aplicación o
solicitud explícita en el fuente-, C# también proporciona un mecanismo de liberación de
recursos determinista a través de la instrucción using.
Seguridad de tipos: C# incluye mecanismos que permiten asegurar que los accesos a
tipos de datos siempre se realicen correctamente, lo que permite evita que se produzcan
errores difíciles de detectar por acceso a memoria no perteneciente a ningún objeto y es
especialmente necesario en un entorno gestionado por un recolector de basura. Para ello
se toman medidas del tipo:
 Sólo se admiten conversiones entre tipos compatibles. Esto es, entre un tipo y
antecesores suyos, entre tipos para los que explícitamente se haya definido un
operador de conversión, y entre un tipo y un tipo hijo suyo del que un objeto del
primero almacenase una referencia del segundo (downcasting) Obviamente, lo
último sólo puede comprobarlo en tiempo de ejecución el CLR y no el
compilador, por lo que en realidad el CLR y el compilador colaboran para
asegurar la corrección de las conversiones.
 No se pueden usar variables no inicializadas. El compilador da a los campos un
valor por defecto consistente en ponerlos a cero y controla mediante análisis del
flujo de control del fuente que no se lea ninguna variable local sin que se le haya
asignado previamente algún valor.
 Se comprueba que todo acceso a los elementos de una tabla se realice con
índices que se encuentren dentro del rango de la misma.
 Se puede controlar la producción de desbordamientos en operaciones
aritméticas, informándose de ello con una excepción cuando ocurra. Sin embargo,
para conseguirse un mayor rendimiento en la aritmética estas comprobaciones no
se hacen por defecto al operar con variables sino sólo con constantes (se pueden
detectar en tiempo de compilación)
 A diferencia de Java, C# incluye delegados, que son similares a los punteros a
funciones de C++ pero siguen un enfoque orientado a objetos, pueden almacenar
referencias a varios métodos simultáneamente, y se comprueba que los métodos a
los que apunten tengan parámetros y valor de retorno del tipo indicado al
definirlos.
7





Pueden definirse métodos que admitan un número indefinido de parámetros de un
cierto tipo, y a diferencia lenguajes como C/C++, en C# siempre se comprueba
que los valores que se les pasen en cada llamada sean de los tipos apropiados.
Instrucciones seguras: Para evitar errores muy comunes, en C# se han impuesto una
serie de restricciones en el uso de las instrucciones de control más comunes. Por ejemplo,
la guarda de toda condición ha de ser una expresión condicional y no aritmética, con lo
que se evitan errores por confusión del operador de igualdad (==) con el de asignación
(=); y todo caso de un switch ha de terminar en un break o goto que indique cuál es la
siguiente acción a realizar, lo que evita la ejecución accidental de casos y facilita su
reordenación.
Sistema de tipos unificado: A diferencia de C++, en C# todos los tipos de datos que se
definan siempre derivarán, aunque sea de manera implícita, de una clase base común
llamada System.Object, por lo que dispondrán de todos los miembros definidos en ésta
clase (es decir, serán "objetos")
A diferencia de Java, en C# esto también es aplicable a los tipos de datos básicos
Además, para conseguir que ello no tenga una repercusión negativa en su nivel de
rendimiento, se ha incluido un mecanismo transparente de boxing y unboxing con el que
se consigue que sólo sean tratados como objetos cuando la situación lo requiera, y
mientras tanto puede aplicárseles optimizaciones específicas.
El hecho de que todos los tipos del lenguaje deriven de una clase común facilita
enormemente el diseño de colecciones genéricas que puedan almacenar objetos de
cualquier tipo.
Extensibilidad de tipos básicos: C# permite definir, a través de estructuras, tipos de
datos para los que se apliquen las mismas optimizaciones que para los tipos de datos
básicos. Es decir, que se puedan almacenar directamente en pila (luego su creación,
destrucción y acceso serán más rápidos) y se asignen por valor y no por referencia. Para
conseguir que lo último no tenga efectos negativos al pasar estructuras como parámetros
de métodos, se da la posibilidad de pasar referencias a pila a través del modificador de
parámetro ref.
Extensibilidad de operadores: Para facilitar la legibilidad del código y conseguir que
los nuevos tipos de datos básicos que se definan a través de las estructuras estén al mismo
nivel que los básicos predefinidos en el lenguaje, al igual que C++ y a diferencia de Java,
C# permite redefinir el significado de la mayoría de los operadores -incluidos los de
conversión, tanto para conversiones implícitas como explícitas- cuando se apliquen a
diferentes tipos de objetos.
Las redefiniciones de operadores se hacen de manera inteligente, de modo que a partir de
una única definición de los operadores ++ y -- el compilador puede deducir
automáticamente como ejecutarlos de manera prefijas y postifja; y definiendo operadores
simples (como +), el compilador deduce cómo aplicar su versión de asignación
compuesta (+=) Además, para asegurar la consistencia, el compilador vigila que los
operadores con opuesto siempre se redefinan por parejas (por ejemplo, si se redefine ==,
también hay que redefinir !=)
También se da la posibilidad, a través del concepto de indizador, de redefinir el
significado del operador [] para los tipos de dato definidos por el usuario, con lo que se
8



consigue que se pueda acceder al mismo como si fuese una tabla. Esto es muy útil para
trabajar con tipos que actúen como colecciones de objetos.
Extensibilidad de modificadores: C# ofrece, a través del concepto de atributos, la
posibilidad de añadir a los metadatos del módulo resultante de la compilación de
cualquier fuente información adicional a la generada por el compilador que luego podrá
ser consultada en tiempo ejecución a través de la librería de reflexión de .NET . Esto, que
más bien es una característica propia de la plataforma .NET y no de C#, puede usarse
como un mecanismo para definir nuevos modificadores.
Versionable: C# incluye una política de versionado que permite crear nuevas versiones
de tipos sin temor a que la introducción de nuevos miembros provoquen errores difíciles
de detectar en tipos hijos previamente desarrollados y ya extendidos con miembros de
igual nombre a los recién introducidos.
Si una clase introduce un nuevo método cuyas redefiniciones deban seguir la regla de
llamar a la versión de su padre en algún punto de su código, difícilmente seguirían esta
regla miembros de su misma signatura definidos en clases hijas previamente a la
definición del mismo en la clase padre; o si introduce un nuevo campo con el mismo
nombre que algún método de una clase hija, la clase hija dejará de funcionar. Para evitar
que esto ocurra, en C# se toman dos medidas:
 Se obliga a que toda redefinición deba incluir el modificador override, con lo que
la versión de la clase hija nunca sería considerada como una redefinición de la
versión de miembro en la clase padre ya que no incluiría override. Para evitar que
por accidente un programador incluya este modificador, sólo se permite incluirlo
en miembros que tengan la misma signatura que miembros marcados como
redefinibles mediante el modificador virtual. Así además se evita el error tan
frecuente en Java de creerse haber redefinido un miembro, pues si el miembro con
override no existe en la clase padre se producirá un error de compilación.
 Si no se considera redefinición, entonces se considera que lo que se desea es
ocultar el método de la clase padre, de modo que para la clase hija sea como si
nunca hubiese existido. El compilador avisará de esta decisión a través de un
mensaje de aviso que puede suprimirse incluyendo el modificador new en la
definición del miembro en la clase hija para así indicarle explícitamente la
intención de ocultación.
Eficiente: En principio, en C# todo el código incluye numerosas restricciones para
asegurar su seguridad y no permite el uso de punteros. Sin embargo, y a diferencia de
Java, en C# es posible saltarse dichas restricciones manipulando objetos a través de
punteros. Para ello basta marcar regiones de código como inseguras (modificador unsafe)
y podrán usarse en ellas punteros de forma similar a cómo se hace en C++, lo que puede
resultar vital para situaciones donde se necesite una eficiencia y velocidad procesamiento
muy grandes.
Compatible: Para facilitar la migración de programadores, C# no sólo mantiene una
sintaxis muy similar a C, C++ o Java que permite incluir directamente en código escrito
en C# fragmentos de código escrito en estos lenguajes, sino que el CLR también ofrece, a
través de los llamados Platform Invocation Services (PInvoke), la posibilidad de
acceder a código nativo escrito como funciones sueltas no orientadas a objetos tales como
las DLLs de la API Win32. Nótese que la capacidad de usar punteros en código inseguro
9
permite que se pueda acceder con facilidad a este tipo de funciones, ya que éstas muchas
veces esperan recibir o devuelven punteros.
También es posible acceder desde código escrito en C# a objetos COM. Para facilitar
esto, el .NET Framework SDK incluye una herramientas llamadas tlbimp y regasm
mediante las que es posible generar automáticamente clases proxy que permitan,
respectivamente, usar objetos COM desde .NET como si de objetos .NET se tratase y
registrar objetos .NET para su uso desde COM.
Finalmente, también se da la posibilidad de usar controles ActiveX desde código .NET y
viceversa. Para lo primero se utiliza la utilidad aximp, mientras que para lo segundo se
usa la ya mencionada regasm.
4. Creación y manejo de hilos en C#

La clase principal para la creación de hilos y el manejo de estos es
System.Threading.Thread, esta clase tiene una cantidad métodos de los cuales
resaltaremos los siguientes:
Start(): inicia la ejecución, de un hilo, lo pone listo para ejecución.
Thread thread = new Thread(new ThreadStart( WriteData ));
thread.Start();
WriteData is la funcion ejecutada por el hilo.
protected void WriteData()
{
string str ;
for ( int i = 0; i<=10000; i++ )
{
str = "Secondary Thread" + i.ToString();
Console.WriteLine(listView1.ListItems.Count,
string[]{""} );
Update();
}
}
str,
0,
new

Suspend(): suspende el hilo indefinidamente, si este esta ya suspendido no pasa nada.
if (thread.ThreadState == ThreadState.Running )
{
thread.Suspend();
}

Resume() : Activa al hilo suspendido, poniéndolo en listo para ejecución.
if (thread.ThreadState == ThreadState.Suspended )
{
thread.Resume();
}
10



Interrupt(): interrumpe a un hilo que se encuentra en un estado wait, sleep, join
Join(): blocks a calling thread until the thread terminates.
Sleep(int x) : Suspende un hilo por una cantidad de tiempo especifico en milisegundos.
While(s==0)
{thread.Sleep(5000);}

Abort(): Termina la participación de un hilo.
if ( thread.IsAlive )
{
thread.Abort();
}
Esta clase tambien cuenta con numero de propiedades interasantes
IsAlive: si regresa verdadero significa que el hilo no a sido abortado o terminado.
Name :pone ó obtiene el nombre del hilo.
Priority: pone ó obtiene la planificación de prioridad del hilo.
ThreadState: obtiene un valor con el estado del hilo.
using System;
using System.Threading ;
namespace LearnThreads
{
class Thread_App
{
public static void First_Thread()
{
Console.WriteLine("First thread created");
Thread current_thread = Thread.CurrentThread;
string
thread_details
=
"Thread
Name:
"
+
current_thread.Name +
"\r\nThread State: " + current_thread.ThreadState.ToString()+
"\r\n
Thread
Priority
level:"+current_thread.Priority.ToString();
Console.WriteLine("The details of the thread are :"+
thread_details);
Console.WriteLine ("first thread terminated");
}
public static void Main()
{
ThreadStart thr_start_func = new ThreadStart (First_Thread);
11
Console.WriteLine ("Creating the first thread ");
Thread fThread = new Thread (thr_start_func);
fThread.Name = "first_thread";
fThread.Start (); //starting the thread
}
}}
Mostramos la siguiente tabla donde se explica los métodos mencionados, en el lenguaje
nativo de la información
Thread
management
functions
A mapping between Java's java.lang.Thread methods and their equivalent in C#'s
System.Threading.Thread object
Java
C#
setDaemon(
boolean
method
IsBackground
on) property
isDaemon()
method
IsBackground
property
isAlive() method
IsAlive get property
Notes
set Makes a given thread a daemon thread (the
program will terminate when all that is left are
daemon threads).
get Returns true if the thread is a background thread.
Returns true if the thread is alive.
interrupt() method Interrupt() method
While in Java this sets the "interrupted status" of
the thread and can be checked to see whether a
thread has been interrupted, there is no such
equivalent check in C#. However, in C#, calling
Interrupt on a thread that is not blocking will cause
the next blocking call to automatically unblock.
isInterrupted()
method
Returns true if this thread has been interrupted.
n/a
sleep( long millis Sleep(
int
) and sleep( long millisecondTimeout )
millis, int nanos ) and
Sleep(
System.TimeSpan
)
methods
join(), and join(
long millis ), and
join( long millis,
int
nanos
)
A static call that pauses the thread of execution for
a given amount of time or until the thread is
interrupted -- this method will throw a
java.lang.InterruptedException in Java and a
System.Threading. ThreadInterruptedException in
C# (remember that all C# exceptions are run-time).
Join(),
Join(
int Unlike the Java join methods which are simply
millisecondTimeout ), timeouts, the C# versions return a boolean upon
and
Join( termination to signify whether the thread died
System.TimeSpan
)
12
methods
methods
(true) or the timeout expired (false).
suspend() method Suspend() method
Functionally the same -- the C# methods exhibit
the same properties that caused the suspend()
method in java.lang.Thread to be deprecated. This
method is deadlock-prone: if a thread holding a
lock on a system-critical resource is suspended,
then no other threads can access the resource until
the former thread is resumed.
resume() method
Resume() method
Resumes a suspended thread.
stop() method
Abort() method
See "Stopping Threads" following this table.
La propiedad System.Threading.Thread.ThreadState define el estado en el que se encuentra un
hilo en un determinado momento. Cuando un hilo es creado, el estado de este es Unstarted.
Cuando un hilo ejecuta el metodo start() el estado del hilo entra en Running, y se queda en este
estado, hasta que no sea suspendido, mandado a dormir, abortado ó termine la ejecución del hilo.
Cuando el hilo es suspendido cambia al estado suspendido, hasta que otro hilo lo reactive, y
regrese al estado Running, cuando el hilo es abortado o ha llegado a su fin el estado en que entra
es Stopped (estado final en que terminaran todos los hilos en condiciones nomales). Existe otro
estado del hilo llamado Background el cual nos indica sin un hilo se encuentra en ejecutándose
en primer plano (foreground) o según plano (background).
Acá mostramos la tabla en de lo estados de un hilo inglés para un mejor entendimiento
Member
Aborted
Description
The thread is in the Stopped state.
The ThreadAbort method has been invoked on the thread, but the thread has
AbortRequested not yet received the pending System.Threading.ThreadAbortException that
will attempt to terminate it.
The thread is being executed as a background thread, as opposed to a
foreground thread. This state is controlled by setting the IsBackground
Background
property of the Thread class.
The thread has been started, it is not blocked, and there is no pending
Running
ThreadAbortException.
The thread has stopped.
Stopped
The thread is being requested to stop. This is for internal use only.
StopRequested
The thread has been suspended.
Suspended
SuspendRequested The thread is being requested to suspend.
The Thread.Start method has not been invoked on the thread.
Unstarted
13
WaitSleepJoin
The thread is blocked as a result of a call to Wait, Sleep or Join methods.
La Propiedad priority de un hilo significa la importancia en ejecutar esa tarea de una manera mas
rápida asignándole de esta manera mayor cantidad de recursos del computador. Existen dos
posiciones para hacer cumplir las necesidades de prioridad una es asignando mayor cantidad de
tiempo de procesador para una tarea( lo cual pondría en peligro la multitarea) o dar mayor
frecuencia de utilización del procesador a estos.
Los diferentes valores de prioridad en C# son los sguientes:
Highest, AboveNormal, Normal, BelowNormal, Lowest
5. Sincronización de hilos
C# nos ofrece una serie de clases que nos ayudan a manejar problemas de acceso a recursos
compartidos, sincronización entre procesos, creación de operaciones atómicas.
De esta manera también demos saber evitar lo problemas clásicos de data- races, deadlocks and
starvation.
Las clases de sincronización son las siguientes:
La clase Monitor
La clase monitor es utilizada en caso en que queremos evitar el acceso concurrente a un pedazo
de código en un tiempo dado. Todos lo métodos en esta clase son static, así que no necesitamos
instanciar la clase esta clase los metodos que utiliza esta clase son los siguientes:
·
Enter, TryEnter
·
Exit
·
Pulse / PulseAll
·
Wait
Uno puede sincronizar el acceso a un pedazo de código bloqueando o desbloqueando un objeto
particular los metodos Monitor.Enter, Monitor.TryEnter and Monitor.Exit son usados para
bloquear o desbloquear un objeto.Una vez que un bloqueo se hace a una porción de código
(Monitor.Enter(object)), ningun otro hilo podra bloquear la misma región de codigo.
El bloqueo puede ser liberado usando Monitor.Exit(object) or Monitor.Wait. Cuando el
desbloqueo es realizado, el método Monitor.Pulse and Monitor.PulseAll apunta y avisa al
siguiente hilo en la cola de listos para bloquear la porción de código
public
{
void
some_method()
14
int a=100;
int b=0;
Monitor.Enter(this);
//say we do something here.
int c=a/b;
Monitor.Exit(this);
} //en este caso nunca se llegará a ejecutar la sección de desbloqueo ya que ocurrirá un error, si
queremos evitar esto tendremos que utilizar la función lock que actúa igual que
Monitor.Enter(this);
public
void
some_method()
{
int a=100;
int b=0;
lock(this);
//say we do something here.
int c=a/b;
}
Mostramos la siguiente tabla de los métodos de la clase monitor en ingles(lenguaje nativo de la
información) para un mejor entendimiento
Thread
synchronization
The keywords to know when wanting to synchronize actions between threads in the two
languages
Java
C#
Notes
synchronized
lock
The C# lock statement is actually syntactic sugar for using
the System.Threading.Monitor class's Enter and Exit
methods
Object.wait()
Monitor.Wait(
object obj )
There is no wait method inherent to an Object. To wait for
a signal, the System.Threading.Monitor class needs to be
used instead. Both of these methods need to be executed
in synchronized blocks
Object.notify() Monitor.Pulse(
object obj )
See the notes for Monitor.Wait above
Object.notify() Monitor.PulseAll(
object obj )
See the notes for Monitor.Wait above
Mutex Class
15
El comportamiento de esta clase es similar al comportamiento de la clase Monitor explicado
anteriormente
Public
{
void
some_method()
int a=100;
int b=20;
Mutex firstMutex = new Mutex(false);
FirstMutex.WaitOne();
//some kind of processing can be done here.
Int x=a/b;
FirstMutex.Close();
}



WaitOne: accepts a wait handle (as an argument) and causes the calling thread to wait
until the current wait handle signal by calling Set.
WaitAny: accepts an array of wait handles (as an argument) and causes the calling
thread to wait until any one of the specified wait handles signal by calling Set.
WaitAll: accepts an array of wait handles (as an argument) and causes the calling
thread to wait until all specified wait handles signal by calling Set
Señales: Son interrupciones asíncronas que se envían de un hilo a otro en el mismo proceso.
Conceptualmente son como las señales de UNIX, salvo que se envían entre hilos en vez de entre
procesos. Las señales se pueden enviar, capturar o ignorar.
b) Mútex: Es como un semáforo binario. Su funcionamiento es el de un mútex típico. Puede tener
un estado entre dos posibles, cerrado o no cerrado. Si se intenta cerrar un mútex no cerrado, se
cierra, y el hilo que realizó la llamada continúa su ejecución. Pero si se intenta cerrar un mútex
ya cerrado, el hilo que realizó la llamada se bloquea hasta que otro hilo libere la cerradura del
mútex. Cuando más de un hilo espera bloqueado por un mútex, cuando éste se libera, se
desbloquea a un único hilo. También existen una llamada en la que se intenta cerrar el mútex,
pero si no se puede hacer durante un determinado intervalo de tiempo, finaliza y devuelve un
error al hilo que realizó la llamada.
c) Semáforos: Los semáforos son más lentos que los mútex, pero su funcionamiento es similar, y
existen ocasiones en que son necesarios. Su funcionamiento es el habitual descrito por Dijkstra.
Existen operaciones P y V para el semáforo, pero además existe una operación DOWN que si no
tiene éxito durante cierto intervalo de tiempo, termina.
Synchronization Events
Hemos visto que los objetos de exclusión mutua, monitores se utilizan normalmente para
sincronizar accesoa datos, en cambio los eventos se utilizan para que un hilo pueda comunicar a
otro que un evento ha ocurrido.
AutoResetEvent Class
Se utilizan cuando las funciones de espera lock no pasan automáticamente al estado ocupado.
16
ManualResetEvent Class
Se utilizan cuando las funciones de espera lock pasan automáticamente al estado ocupado.
Interlocked Class
Sirve para sincronizar el acceso a variable que están siendo accedidas por muchos hilos,
provenido el aseguramiento de operaciones atómicas. Entre sus métodos tenemos
Interlocked.Increment y Interlocked.Decrement que sirven para incrementar ó decrementar
una variable de manera atómica, también poner un valor en una variable utilizando
Interlocked.Exchange, tambien comparar el valor de dos variables, si son iguales remplaza
una de las variables con un valor determinado Interlocked.CompareExchange.
ReaderWriterLock class
Esta clase define un bloqueo en el proceso de escritura y lectura. Esta clase ofrece
sincronización de lectura y escritura. Cualquier cantidad de hilos pueden leer los datos
concurrentemente pero al escribir, y el bloqueo sucede cuando alguien quiere actualizar una
de las variables. Los hilos lectores pueden acceder a bloque cuando no haya hilos escritores,
y los hilos escritores accederán al bloque cuando no haya hilos escritores ni lectores.
ReaderWriterLock.AcquireReaderLock, ReaderWriterLock.ReleaseLock funciones de bloqueo
y desbloqueo
Pasar de ser hilo escritor a ser hilo lector y viceversa
ReaderWriterLock.UpgradeToWriterLock, ReaderWriterLock.DowngradeFromWriterLock.
6. Conclusiones

Parece ser que existirá una disputa tecnológica entre Sun Microsystems y Microsoft
Corp. En lo que es programación web debido al gran avance que Microsoft ha dado con
la creación de .NET y de la portabilidad de las aplicaciones.

El C# como abanderado de .NET aparenta tener mayor potencia en progrmación y
velocidad de las aplicaciones creadas, debido a que junta las características de C++ y de
JAVA además que
MSIL (Microsoft Intermediate Language) parece ser mas potente en ejecución que los
bytecodes de JAVA


Nos hemos dado cuenta que programar en C# requiere un buen entendimiento de la
tecnología de objetos ya que es casi un lenguaje puro OO. Por habra primero que
entender a la perfección el manejo de clases y objetos, toda la tecnología de objetos para
tener éxito programando en C#

Respecto a las caracteríticas de C# en lo que es programación paralela, son superiores a
las de C++ y JAVA ya que las clases son mas robustas en detalles como propiedades,
métodos que no evitan estar programando demás.

En términos generales el fundamento teórico de elementos de sincronización como
mutex, señales, semaforos son muy parecidas a las de todos los lenguajes pero las clases
en C# cuentan con mayor cantidad de propiedades que nos permiten analizar el estado de
estos objetos.
17

La orientación de objetos de este lenguaje es determinante para entender la utilización de
los objetos de sincronización ya que todos estos toman como parámetros objetos callers.

Las características generales de lenguaje de programación son demasiado útiles y
desestrezantes para la programación ya que cuenta con muchos clases de control, ademas
de las propiedades inherentes del lenguaje explicadas al inicio del paper.
7. Referencias
http://tdg.lsi.us.es/ pagina que contiene la explicación clara de C# y .NET y su correspondencia
de acá sacamos la parte de C# y .Net
www.C#Corner.com pagina que contiene infinidad de artículos publicados y información
de C# en Inglés de acá sacamos la parte hilos.
www.csharphelp.com Pagina contiene infinidad de artículos de C# en Ingles, también
usamos esta pagina para la parte hilos
18