11.- Desarrollo de Componentes en Visual Basic .NET

63
  Desarrollo de componentes en Visual Basic .NET Índice Descripción 1 Descripción de los componentes 2 Creación de componentes con servicio 11 Demostración: creación de un componente con servicio 29 Creación de clases de componentes 31 Demostración: Creación de un componente Stopwatch 37 Creación de controles de formularios Windows Forms 39 Demostración: Creación de una caja de texto mejorada 46 Manejo de hilos de ejecución 48 Demostración: Uso de la instrucción SyncLock 61

Transcript of 11.- Desarrollo de Componentes en Visual Basic .NET

Desarrollo de componentes en Visual Basic .NET

ndice Descripcin Descripcin de los componentes Creacin de componentes con servicio Demostracin: creacin de un componente con servicio Creacin de clases de componentes Demostracin: Creacin de un componente Stopwatch Creacin de controles de formularios Windows Forms Demostracin: Creacin de una caja de texto mejorada Manejo de hilos de ejecucin Demostracin: Uso de la instruccin SyncLock 1 2 11 29 31 37 39 46 48 61

Desarrollo de componentes en Visual Basic .NET

1

DescripcinObjetivoPresentar los temas y objetivos del mdulo.

Presentacin

Components Overview Creating Serviced Components Creating Component Classes Creating Windows Forms Controls Creating Web Forms User Controls Threading

En este mdulo, aprenderemos cmo crear componentes en Visual Basic .NET.

Como desarrolladores de Microsoft Visual Basic, seguramente ya sabemos cmo desarrollar y utilizar componentes en nuestras aplicaciones. En Visual Basic .NET, podemos utilizar las nuevas caractersticas en tiempo de diseo para crear fcilmente componentes y extender sus funcionalidades. En este mdulo, aprenderemos a: Describir los distintos tipos de componentes que pueden crearse en Visual Basic .NET. Crear componentes que pueden ser utilizados por aplicaciones cliente gestionadas y no gestionadas. Crear componentes con servicio Crear clases de componentes Crear controles de formularios Windows Forms. Utilizar hilos para crear aplicaciones con mltiples hilos de ejecucin.

2

Desarrollo de componentes en Visual Basic .NET

Descripcin de los componentesObjetivoOfrecer una descripcin de los temas tratados en esta leccin.

Tipos de componentes Uso d mdulos como componentes Uso de clases como componentes Uso de componentes en aplicaciones cliente no gestionadas Descripcin de .NET Remoting

Presentacin

Esta leccin explica los tipos de componentes que podemos crear en una aplicacin basada en Visual Basic .NET y cmo podemos hacerlos visibles para aplicaciones cliente no gestionadas. Tambin proporciona una descripcin de .NET Remoting para la comunicacin entre componentes.

En Visual Basic .NET, podemos crear varios tipos de componentes accesibles tanto desde aplicaciones cliente gestionadas (las basadas en los servicios del entorno de ejecucin del .NET Framework) y aplicaciones cliente no gestionadas (por ejemplo, las creadas en Visual Basic 6.0). En esta leccin, aprenderemos a: Describir los tipos de componentes que podemos crear en Visual Basic .NET. Utilizar mdulos y clases como componentes. Utilizar componentes basados en Visual Basic .NET en entornos no gestionados. Explicar los principales conceptos de .NET Remoting.

Desarrollo de componentes en Visual Basic .NET

3

Tipos de componentesObjetivoExplicar los diferentes tipos de componentes que podemos crear en Visual Basic .NET.

Estructuras Mdulos Clases Clases de componente Componentes con servicio Controles de usuario Controles de usuario de formularios Windows Forms Controles de usuario de formularios Web Forms

Presentacin

Podemos crear varios tipos de componentes en una aplicacin basada en Visual Basic .NET.

En Visual Basic .NET, podemos crear varios tipos de componentes distintos, incluyendo: Sugerencia Estructuras Mdulos Clases Clases de componentes Componentes con servicio Controles de usuario

Comentar que este mdulo se centra en cmo crear y utilizar clases de componentes, componentes con servicio y controles de usuario. El resto de tipos de componentes se mencionan nicamente como referencia.

EstructurasPodemos utilizar las estructuras como componentes declarndolas pblicas cuando las definamos. Las estructuras soportan muchas de las caractersticas de las clases, incluyendo propiedades, mtodos y eventos, pero son de tipo valor; por tanto, la gestin de la memoria es ms eficaz. Las estructuras no soportan herencia.

MdulosPodemos utilizar los mdulos como componentes declarndolos pblicos cuando los definamos. Declarar mdulos pblicos permite crear libreras de cdigo que contienen rutinas tiles para mltiples aplicaciones. Tambin podemos utilizar mdulos para crear funciones reutilizables que no son de aplicacin a un componente, clase o estructura concretos. Si hemos utilizado las clases GlobalMultiUse o GlobalSingleUse en versiones anteriores de Visual Basic, el concepto de librera de cdigo no nos resultar nuevo. Estas clases proporcionan la misma funcionalidad en Visual Basic .NET; el cdigo cliente no necesita cualificar estas clases por el nombre de clase para invocar las funciones.

4

Desarrollo de componentes en Visual Basic .NET

ClasesPodemos utilizar clases como componentes declarndolas pblicas en un ensamblado. Podemos utilizar clases pblicas desde cualquier aplicacin cliente basada en .NET agregando una referencia al ensamblado del componente. Podemos extender la funcionalidad de las clases mediante mecanismos como propiedades, mtodos y eventos. Las clases tambin son extensibles mediante la herencia, lo cual permite a las aplicaciones reutilizar la lgica existente en estos componentes.

Clases de componentesUna clase se convierte en componente cuando se ajusta a un estndar para la interaccin con componentes. Este estndar se proporciona a travs de la interfaz IComponent. Cualquier clase que implemente la interfaz IComponent es un componente. Las clases de componentes permiten abrir la clase en un diseador visual y permiten a la clase ser ubicada en otros diseadores visuales.

Componentes con servicioLos componentes con servicio derivan directa o indirectamente de la clase System.EnterpriseServices.ServicedComponent. Las clases configuradas de este modo son hospedadas por una aplicacin de servicios de componentes y pueden automticamente utilizar los servicios que sta ofrece.

Controles de usuarioLos controles de usuario son componentes creados por un desarrollador para ubicarlos en formularios Windows Forms o Web Forms. Cada control de usuario tiene su propio conjunto de propiedades, mtodos y eventos que lo hacen adecuado para un determinado uso. Podemos manipular controles de usuario en los diseadores de formularios Windows Forms y Web Forms y escribir cdigo para agregar controles de usuario dinmicamente en el entorno de ejecucin, al igual que con los controles proporcionados como parte del .NET Framework. Nota En este mdulo, aprenderemos cmo crear y utilizar clases de componentes, componentes con servicio y controles de usuario.

Desarrollo de componentes en Visual Basic .NET

5

Uso de mdulos como componentesObjetivoExplicar cmo utilizar mdulos como componentes.

Declarar el mdulo como pblico Referenciar e importa el ensamblado en cdigo clientePublic Module MyMathFunctions Public Module MyMathFunctions Public Function Square(ByVal lng As Integer) As Long Public Function Square(ByVal lng As Integer) As Long Return (lng * lng) Return (lng * lng) End Function End Function ... ... End Module End Module 'Client code 'Client code Imports MyAssembly Imports MyAssembly ... ... Dim x As Long = Square(20) Dim x As Long = Square(20)

Presentacin

En Visual Basic .NET, podemos utilizar mdulos como componentes fuera del ensamblado en el que estn definidos.

En Visual Basic .NET podemos utilizar mdulos como componentes fuera del ensamblado en el que estn definidos. Para que esto sea posible, debemos declarar el mdulo como pblico cuando lo definamos. A continuacin, necesitaremos crear una referencia en el ensamblado cliente al ensamblado componente y utilizar la instruccin Imports para permitir el acceso a los mtodos del mdulo. El siguiente ejemplo muestra cmo crear un mdulo pblico denominado MyMathFunctions que define la funcin Square. Este mdulo est definido en el ensamblado MyAssembly. A continuacin, el mdulo puede utilizarse como un componente en el cdigo cliente, como muestra la segunda parte del ejemplo.Public Module MyMathFunctions Public Function Square(ByVal lng As Long) As Long Return (lng * lng) End Function ... End Module 'Client code Imports MyAssembly ... Dim x As Long = Square(20)

6

Desarrollo de componentes en Visual Basic .NET

Uso de clases como componentesObjetivoExplicar cmo utilizar clases como componentes.

Presentacin

Declarar la clase como pblica Referenciar e importar el ensamblado en cdigo clientePublic Class Account Public Class Account Public Sub Debit(ByVal AccountId As Long, Amount As Double) Public Sub Debit(ByVal AccountId As Long, Amount As Double) 'Perform debit action 'Perform debit action End Sub End Sub Public Sub Credit(ByVal AccountId As Long, Amount As Double) Public Sub Credit(ByVal AccountId As Long, Amount As Double) 'Perform credit action 'Perform credit action End Sub End Sub End Class End Class 'Client code 'Client code Imports MyAssembly Imports MyAssembly Dim x As New Account( ) Dim x As New Account( ) x.Debit(1021, 1000) x.Debit(1021, 1000)

En Visual Basic .NET, podemos utilizar clases como componentes.

Podemos utilizar clases como componentes fuera del ensamblado en el que estn definidas marcando la clase como pblica. A continuacin, referenciamos el ensamblado del componente desde el ensamblado cliente, y utilizamos la instruccin Imports para permitir el acceso directo a la clase. El siguiente ejemplo muestra cmo crear una clase pblica denominada Account que define los mtodos Debit y Credit. Esta clase est definida en el ensamblado MyAssembly. A continuacin, otro ensamblado cliente referencia el ensamblado, y la clase puede utilizarse por instancias de objetos.Public Class Account Public Sub Debit(ByVal AccountId As Long, Amount As Double) 'Perform debit action End Sub Public Sub Credit(ByVal AccountId As Long, Amount As Double) 'Perform credit action End Sub End Class 'Client code Imports MyAssembly Dim x As New Account( ) x.Debit(1021, 1000)

Desarrollo de componentes en Visual Basic .NET

7

Uso de componentes en aplicaciones cliente no gestionadasObjetivoExplicar cmo crear componentes que pueden ser utilizados por aplicaciones cliente no gestionadas, como clientes basados en Visual Basic 6.0.

Setting assembly properties Generate a strong name Select Register for COM Interop in Build options Exposing class members to COM and Component Services Define and implement interfaces Use the ClassInterface attribute with AutoDual value Use the COMClass attribute

Presentacin

Podemos utilizar COM para que todos los componentes de Visual Basic .NET sean accesibles desde clientes no gestionados, siguiendo unos sencillos pasos.

Podemos crear componentes con Visual Basic .NET que pueden ser utilizados por aplicaciones cliente no gestionadas. Esta interoperabilidad permite utilizar caractersticas de los servicios de componentes como la agrupacin de objetos o las transacciones. Para exponer nuestros componentes a COM y a los servicios de componentes, debemos establecer propiedades especficas del ensamblado y crear nuestras clases adecuadamente.

Establecer propiedades del ensambladoDebemos proporcionar a nuestro ensamblado un nombre seguro si deseamos que sea accesible desde cdigo no gestionado. Para crear un ensamblado de nombre seguro, utilizaremos un par de claves privada y pblica al generar la aplicacin, para garantizar que el ensamblado es nico y no puede modificarse de forma inadecuada despus de que haya sido generado.

Poner nombre al ensambladoPodemos generar un nombre seguro para nuestro ensamblado utilizando la herramienta de nombres seguros (sn.exe) incluida en el .NET Framework. El siguiente cdigo muestra cmo utilizar sn.exe para generar un archivo de claves denominado KeyFile.snk:sn.exe k KeyFile.snk

Una vez generado el archivo de claves, podemos agregarlo al proyecto y referenciarlo en AssemblyInfo.vb utilizando el siguiente cdigo:

De este modo, nuestro ensamblado tendr un nombre seguro la prxima vez que lo generemos.

8

Desarrollo de componentes en Visual Basic .NET

Registro del ensambladoPodemos registrar automticamente un ensamblado que necesita interoperabilidad con COM en la seccin Propiedades de configuracin de las pginas de propiedades del ensamblado. La seccin Generar proporciona una casilla de verificacin Registrar para COM Interop. Si la seleccionamos, nuestro ensamblado se registra con COM cuando se genere la prxima vez. Si regeneramos ms veces nuestro ensamblado tras el registro inicial, primero se eliminar del registro antes de ser registrado de nuevo. Este proceso garantiza que el registro no contiene informacin desactualizada.

Exponer miembros de clases a COM y a los servicios de componentesCrear una clase que tenga propiedades y mtodos pblicos no hace que los miembros de la clase estn accesibles en COM y en los servicios de componentes. A menos que expongamos los miembros de clase, la clase en s ser accesible, pero los mtodos no sern accesibles excepto a travs de late binding. Podemos exponer los miembros de clases y permitir early binding: Definiendo una interfaz pblica Utilizando el atributo ClassInterface Utilizando el atributo COMClass.

Definir una interfaz pblicaDefinir una interfaz pblica e implementarla en nuestra clase pblica permite que las aplicaciones cliente no gestionadas puedan ver y enlazarse a los mtodos de la interfaz. Esta aproximacin proporciona el modo ms coherente y seguro de exponer componentes a COM ya que el uso de interfaces evita muchos problemas asociados al versionado. El siguiente cdigo muestra cmo crear una interfaz pblica y, a continuacin, utilizar la interfaz en una clase que estar accesible para aplicaciones cliente no gestionadas a travs de COM:Public Interface IVisible Sub PerformAction( ) End Interface Public Class VisibleClass Implements IVisible Public Sub PerformAction( ) _ Implements IVisible.PerformAction 'Perform your action End Sub End Class

Desarrollo de componentes en Visual Basic .NET

9

Uso del atributo ClassInterfaceEl espacio de nombres System.Runtime.InteropServices proporciona el atributo ClassInterface. Este atributo permite crear una clase con una interfaz dual para que todos los miembros de la clase (y las clases base) estn accesibles automticamente para aplicaciones cliente no gestionadas a travs de COM. El siguiente cdigo muestra cmo utilizar el atributo ClassInterface: SugerenciaImports System.Runtime.InteropServices _ Public Class VisibleClass Public Sub PerformAction( ) 'Perform your action End Sub End Class

Compruebe que los estudiantes saben qu son los interfaces duales. Explquelo brevemente si fuera necesario.

Uso del atributo COMClassEl espacio de nombres Microsoft.VisualBasic proporciona el atributo COMClass que podemos utilizar en una clase para exponer todos los miembros de clase pblicos a COM. Visual Basic .NET proporciona un elemento de plantilla de clase denominado COM Class que podemos agregar a cualquier tipo de proyecto que utilice el atributo COMClass. Cualquier ensamblado que contenga este tipo de clase se registrar cuando sea generado y posteriormente regenerado. Precaucin Los tres planteamientos pueden provocar problemas de versionado si las firmas de mtodos pblicos se modifican entre versiones. Por ello, la implementacin de interfaces es la aproximacin preferida, ya que pueden crearse nuevas interfaces con nuevas firmas de mtodos sin causar dificultades de versionado.

10

Desarrollo de componentes en Visual Basic .NET

Descripcin de .NET RemotingObjetivoOfrecer una descripcin de .NET Remoting.

Cliente AppDomainMarshal By ReferenceCdigo clienteServidor Proxy

Servidor AppDomain

Presentacin

El .NET Framework ofrece varios servicios que se utilizan en remoto.

Formateador

FormateadorObjeto servidor

Canal

Marshal By ValueCdigo clienteCopia objeto servidor

Formateador

Canal

Canal

Lmite de Remoting

Las versiones anteriores de Visual Basic utilizaban COM y la versin distribuida de COM (DCOM) para comunicarse con componentes en diferentes procesos o con distintos equipos. Visual Basic .NET utiliza .NET Remoting para permitir la comunicacin entre aplicaciones cliente y servidor a travs de dominios de aplicaciones. El .NET Framework proporciona varios servicios que se utilizan en remoto: Los canales de comunicacin son los responsables de transportar los mensajes a y desde aplicaciones remotas utilizando tanto un formato binario sobre un canal Transmission Control Protocol (TCP) como Extensible Markup Language (XML) sobre un canal Hypertext Transfer Protocol (HTTP). Formateadores que codifican y decodifican mensajes antes de que sean transportados por el canal. Objetos proxy que envan las invocaciones de mtodos remotos al objeto adecuado. Soporte para la activacin remota de objetos y para la duracin de objetos marshal-by-reference que se ejecutan en el servidor. Objetos marshal-by-value que son copiados por el .NET Framework en el espacio del proceso en el cliente para reducir viajes de ida y vuelta entre procesos o entre equipos. Nota Si deseamos obtener ms informacin sobre .NET Remoting, consultar Microsoft .NET Remoting: introduccin tcnica en la documentacin de Microsoft Visual Studio .NET.

Desarrollo de componentes en Visual Basic .NET

11

Creacin de componentes con servicioObjetivoOfrecer una descripcin de los temas tratados en esta leccin.

Hospedar componentes en Component Services Uso de transacciones Uso del pooling de objetos Uso de cadenas de constructor Uso de seguridad Uso de otros Component Services configuracin de ensamblados para Component Services

Presentacin

Esta leccin examina componentes .NET hospedados por los servicios de componentes.

En esta leccin, aprenderemos a: Describir los requerimientos para hospedar componentes basados en .NET en una aplicacin de servicios de componentes. Habilitar el procesamiento de transacciones en nuestros componentes. Utilizar la agrupacin de objetos para mejorar el rendimiento de los objetos que necesitan recursos adicionales. Utilizar atributos de seguridad para especificar cmo interactan los componentes con la seguridad de los servicios de componentes. Agregar constructores para controlar la inicializacin de un componente. Explicar cmo utilizar otros servicios de componentes, como la activacin Just-In-Time, desde componentes Visual Basic .NET. Establecer atributos a nivel de ensamblado para mejorar la instalacin de nuestra aplicacin.

12

Desarrollo de componentes en Visual Basic .NET

Hospedar componentes en los servicios de componentesObjetivoExplicar los requerimientos para hospedar componentes en los servicios de componentes.

Agregar una referencia a System.EnterpriseServices en el ensamblado El espacio de nombres System.EnterpriseServices proporciona: Clase ContextUtil Clase ServicedComponent Atributos de ensamblado, clase y mtodo

Presentacin

Para permitir que los componentes sean hospedados en los servicios de componentes, el .NET Framework proporciona varios elementos que necesitamos incluir en nuestros ensamblados y en las clases.

Debemos agregar una referencia en el proyecto al espacio de nombres System.EnterpriseServices si deseamos hospedar un componente Visual Basic .NET en una aplicacin de servicios de componentes. Este espacio de nombres proporciona las principales clases, interfaces y atributos para comunicar con los servicios de componentes. El espacio de nombres System.EnterpriseServices proporciona las siguientes caractersticas:Caracterstica Clase ContextUtil Uso Esta clase se utiliza para participar en transacciones y para interactuar con informacin de seguridad. La funcionalidad de esta clase es similar a la funcionalidad de la clase ObjectContext en Visual Basic 6.0. Clase Todas las clases de componentes que necesitan ser hospedadas en ServicedComponent una aplicacin de servicios de componentes deben heredar de esta clase. Esta clase define el tipo base para todos los tipos enlazados a contexto e implementa mtodos similares a los que se encuentran en la interfaz IObjectControl utilizada en las aplicaciones de servicios de componentes basadas en Visual Basic 6.0. Atributos de ensamblado, clase y mtodo Podemos definir varios atributos del ensamblado para la interrogacin a los servicios de componentes en el archivo AssemblyInfo.vb. Estos valores se utilizan para establecer el nombre y la descripcin de la aplicacin y dems valores cuando la aplicacin se instala como una aplicacin de servicios de componentes. El espacio de nombres System.EnterpriseServices tambin define varios atributos de clases y mtodos, incluyendo TransactionAttribute, AutoCompleteAttribute, ObjectPoolingAttribute y ConstructionEnabledAttribute.

Desarrollo de componentes en Visual Basic .NET

13

Nota La parte Attribute de un nombre de atributo es opcional, por tanto, por ejemplo, podemos utilizar AutoComplete o AutoCompleteAttribute en nuestro cdigo.

14

Desarrollo de componentes en Visual Basic .NET

Uso de transaccionesObjetivoExaminar cmo los componentes pueden utilizar transacciones de los servicios de componentes.

El atributo Transaction especifica cmo participa una clase en las transacciones La clase ContextUtil proporciona transaction voting El atributo AutoComplete impide el uso de los mtodosSetAbort, SetComplete y ContextUtil Public Class Account Public Class Account Inherits ServicedComponent Inherits ServicedComponent Public Sub Debit(...) Public Sub Debit(...) 'Perform debit action 'Perform debit action ContextUtil.SetComplete( ) ContextUtil.SetComplete( ) End Sub End Sub Public Sub Credit(...) Public Sub Credit(...) 'Perform credit action 'Perform credit action 'No SetComplete because AutoComplete is on 'No SetComplete because AutoComplete is on End Sub End Sub End Class End Class

Presentacin

Existen varios objetos y atributos que permiten a los componentes de Visual Basic .NET utilizar transacciones de los servicios de componentes.

Con frecuencia, se requieren transacciones para mantener la integridad de los datos y sincronizar actualizaciones de datos entre mltiples fuentes de datos. Podemos habilitar el procesamiento de transacciones en los componentes con servicio incluyendo las clases y atributos adecuados en el cdigo de nuestro componente.

Opciones del atributo TransaccinUtilizamos el atributo Transaction para especificar cmo una clase puede participar en las transacciones. Podemos establecer el soporte de transacciones con una de las siguientes opciones:Opcin Disabled NotSupported Required Efecto La instancia de clase no utilizar transacciones e ignorar las transacciones de objetos padre. La instancia de clase no se crear en el contexto de una transaccin. La instancia de clase se incluir en una transaccin existente proporcionada por el contexto del objeto que realiza la llamada. Si no existe ninguna transaccin, se crear una. La instancia de clase siempre crear una nueva transaccin con independencia de las transacciones ya creadas por objetos que realizan las llamadas. La instancia de clase se incluir en una transaccin si la proporciona el contexto del objeto que realiza la llamada, pero no crear una transaccin si no existe ya una.

RequiresNew

Supported

Desarrollo de componentes en Visual Basic .NET

15

Uso del atributo TransactionEl siguiente ejemplo define una clase Account y establece el atributo Transaction a Required.Imports System.EnterpriseServices Public Class Account Inherits ServicedComponent Public Sub Debit(ByVal id As Integer, _ ByVal amount As Double) 'Debit code End Sub End Class

Opciones de votacin de una transaccinPodemos votar por el resultado de una transaccin utilizando mtodos de la clase ContextUtil, suministrada por el espacio de nombres System.EnterpriseServices. Esta clase esttica proporciona muchos mtodos y propiedades que nos resultarn familiares si hemos creado componentes que utilicen Microsoft Transaction Server (MTS) o los servicios de componentes. A continuacin, se describen algunos de los mtodos ms habituales:Mtodo ContextUtil SetAbort Utilice este mtodo para: Votar por la anulacin de una transaccin. La transaccin slo puede tener xito si todos los objetos implicados en la transaccin votan satisfactoriamente por unanimidad. Este mtodo tambin permite que el objeto sea desactivado despus de que la llamada al mtodo finalice. Votar por la confirmacin de una transaccin. Si todos los objetos implicados en la transaccin votan con xito, la transaccin puede completarse. Este mtodo tambin permite que el objeto sea desactivado despus de que la llamada al mtodo finalice. Votar por una finalizacin exitosa de la transaccin, no permitiendo al objeto ser desactivado despus de que la llamada al mtodo finalice. Esta opcin resulta til si deseamos mantener el estado a travs de mltiples llamadas a mtodos, pero no necesitamos ms acciones para finalizar con xito la transaccin si as lo solicita el componente de servicio de nivel superior. DisableCommit Votar por una finalizacin no exitosa de la transaccin, no permitiendo al objeto ser desactivado despus de que la llamada al mtodo finalice. Esta opcin resulta til si deseamos mantener el estado a travs de mltiples llamadas a mtodos y necesitamos que ocurran otras acciones antes de que la transaccin pueda finalizar con xito.

SetComplete

EnableCommit

16

Desarrollo de componentes en Visual Basic .NET

Uso de la clase ContextUtilEl siguiente ejemplo muestra cmo utilizar la clase ContextUtil para finalizar o abortar transacciones en el mtodo Debit de la clase Account, basndose en las excepciones que se hayan encontrado.Public Sub Debit(ByVal id As Integer, ByVal amount As Double) Try 'Perform update to database ... ContextUtil.SetComplete( ) Catch ex As Exception ContextUtil.SetAbort( ) Throw ex End Try End Sub

Procesamiento de transaccionesPara evitar el uso de los mtodos SetAbort y SetComplete de ContextUtil, podemos establecer el atributo AutoComplete de los mtodos especficos del componente. Si no ocurren excepciones durante la ejecucin del mtodo, el objeto se comporta como si se hubiera invocado SetComplete. Si ocurren excepciones, el objeto se comporta como si se hubiera invocado SetAbort.

Uso del atributo AutoCompleteEl siguiente ejemplo muestra cmo utilizar el atributo AutoComplete:Public Sub Credit( _ ByVal fromAccount As Integer, ByVal amount As Double) 'Perform update to database ... 'No SetComplete or SetAbort is required End Sub

Desarrollo de componentes en Visual Basic .NET

17

Uso de la agrupacin de objetosObjetivoExaminar cmo los componentes pueden utilizar la agrupacin de objetos.

La agrupacin de objetos permite crear los objetos con antelacin El atributo ObjectPooling especifica MinPoolSize y MaxPoolSize ServicedComponent proporciona el mtodo CanBePooled _ Public Class Account Public Class Account Inherits ServicedComponent Inherits ServicedComponent ... ... Protected Overrides Function CanBePooled( ) As Boolean Protected Overrides Function CanBePooled( ) As Boolean Return True Return True End Function End Function End Class End Class

Presentacin

Diversos atributos e interfaces permiten que los componentes de Visual Basic .NET utilicen la agrupacin de objetos.

En Visual Basic .NET, podemos utilizar el atributo ObjectPooling y la clase base ServicedComponent para crear componentes con servicio que utilicen la agrupacin de objetos.

Qu es la agrupacin de objetos?La agrupacin de objetos permite crear con antelacin un nmero prestablecido de objetos, de modo que estn listos para ser usados por peticiones de clientes cuando la aplicacin se inicia. Cuando una aplicacin cliente realiza una peticin de un objeto, se toma uno de la agrupacin de objetos disponibles y se utiliza para esa peticin. Cuando finaliza la peticin, el objeto se devuelve a la agrupacin para que pueda ser utilizado en otras peticiones de clientes. Podemos utilizar la agrupacin para mejorar el rendimiento de objetos que requieran grandes intervalos de tiempo para adquirir recursos y completar una operacin. Los objetos que no necesiten tales recursos no se beneficiarn significativamente de la agrupacin de objetos.

18

Desarrollo de componentes en Visual Basic .NET

Habilitar la agrupacin de objetosEspecificamos el atributo ObjectPooling para que los servicios de componentes puedan ubicar el componente en una agrupacin de objetos. Tambin podemos especificar argumentos opcionales del atributo para establecer los valores MinPoolSize y MaxPoolSize de la agrupacin. MinPoolSize Utilizamos el argumento MinPoolSize para establecer el nmero mnimo de objetos que se crearn con antelacin en la agrupacin. MaxPoolSize Utilizamos el argumento MaxPoolSize para establecer el nmero mximo de objetos que pueden crearse en la agrupacin. Si no hay objetos disponibles en la agrupacin cuando se recibe una peticin, la agrupacin puede crear otra instancia del objeto si ese nmero mximo de objetos preestablecido no se ha alcanzado ya. Si ya se han creado el nmero mximo de objetos y actualmente no hay ninguno disponible, las peticiones se encolarn hasta el prximo objeto disponible.

Devolver objetos a la agrupacin de objetosUtilizamos el mtodo CanBePooled para especificar si nuestro componente puede ser devuelto a la agrupacin de objetos. Los objetos nicamente pueden devolverse a la agrupacin cuando estn desactivados. Esto ocurre cuando se invocan los mtodos SetComplete o SetAbort cuando el objeto es transaccional, o si se invoca explcitamente un mtodo Dispose si el objeto no es transaccional. True Si el componente soporta la agrupacin de objetos y puede devolverse de forma segura a la agrupacin, el mtodo CanBePooled debera devolver True. False Si el componente no soporta la agrupacin de objetos, o si la instancia actual no puede devolverse a la agrupacin, el mtodo CanBePooled debera devolver False.

Nota Si la agrupacin de objetos se deshabilita para un componente, el mtodo CanBePooled no se ejecutar.

Desarrollo de componentes en Visual Basic .NET

19

Uso del mtodo CanBePooledEl siguiente ejemplo muestra cmo crear una agrupacin de objetos para el objeto Account con un nmero mnimo de cinco objetos y un mximo de 50 en un momento dado. El mtodo CanBePooled devuelve True para informar a los servicios de componentes de que el objeto puede devolverse a la agrupacin.Public Class Account Inherits ServicedComponent Public Sub Debit(ByVal id As Integer, _ ByVal amount As Double) ... End Sub Protected Overrides Function CanBePooled( ) As Boolean Return True End Function End Class

20

Desarrollo de componentes en Visual Basic .NET

Uso de las cadenas de constructorObjetivoExplicar cmo los componentes pueden utilizar las cadenas de constructor.

Especifican el atributo ConstructionEnabled para indicar que se necesita una cadena de constructor Reemplazan el mtodo Construct para recuperar informacinPublic Class Account Public Class Account Inherits ServicedComponent Inherits ServicedComponent Protected Overrides Sub Construct(ByVal s As String) Protected Overrides Sub Construct(ByVal s As String) 'Called after class constructor 'Called after class constructor 'Use passed in string 'Use passed in string End Sub End Sub End Class End Class

Presentacin

Los servicios de componentes proporcionan cadenas de constructor a componentes con servicio y son accesibles para componentes de Visual Basic .NET a travs del .NET Framework.

Podemos utilizar una cadena de constructor para controlar cmo se inicializan los componentes con servicio. Esto nos permite especificar cualquier informacin inicial que necesite el objeto, como una cadena de conexin a una base de datos, utilizando la consola de gestin de componentes de los servicios de componentes. Podemos utilizar el atributo ConstructionEnabled para habilitar este proceso en un componente con servicio. Nuestro componente en Visual Basic .NET puede recibir esta informacin del constructor porque la clase heredada ServicedComponent proporciona el mtodo sobrecargable Construct.

Uso del atributo ConstructionEnabledEspecificamos el atributo ConstructionEnabled a nivel de clase para que pueda pasarse al objeto una cadena de constructor durante la construccin del mismo. Podemos modificar este valor cuando el componente se instala como una aplicacin de servicios de componentes utilizando la consola de gestin de Servicios de Componentes.

Uso del mtodo ConstructSobrecargamos el mtodo Construct de la clase base ServicedComponent para recibir el valor de la cadena enviado al componente durante la construccin. El siguiente ejemplo muestra cmo habilitar un constructor, sobrecargar el mtodo Construct y pasar una cadena de constructor almacenada en una variable local.

Desarrollo de componentes en Visual Basic .NETPublic Class Account Inherits ServicedComponent Private strValue As String Protected Overrides Sub Construct(ByVal s As String) 'Called after class constructor strValue = s End Sub End Class

21

22

Desarrollo de componentes en Visual Basic .NET

Uso de seguridadObjetivoExplicar cmo la seguridad de los servicios de componentes es accesible por los componentes de Visual Basic .NET.

Security configuration attributes enable security and role configuration SecurityCallContext class provides role checking and caller information _ _ Public Class Account Public Class Account Inherits ServicedComponent Inherits ServicedComponent Public Function GetDetails( ) As String Public Function GetDetails( ) As String With SecurityCallContext.CurrentCall With SecurityCallContext.CurrentCall If .IsCallerInRole("Manager") Then If .IsCallerInRole("Manager") Then Return .OriginalCaller.AccountName Return .OriginalCaller.AccountName End If End If End With End With End Function End Function End Class End Class

Presentacin

Los servicios de componentes proporcionan informacin de seguridad que pueden utilizar los componentes de Visual Basic .NET.

Cuando se trabaja con componentes con servicio, se pueden utilizar atributos y objetos predefinidos para configurar y probar las opciones de seguridad.

Opciones de los atributos de seguridadPodemos establecer opciones de seguridad utilizando atributos en nuestras clases. Los servicios de componentes utilizarn estos atributos cuando configuremos nuestros componentes tal y como se describe en la siguiente tabla:Atributo ApplicationAccessControl Uso Este atributo a nivel de ensamblado se utiliza para habilitar o deshabilitar explcitamente la comprobacin de acceso a nivel de aplicacin. Este atributo a nivel de componente se utiliza para habilitar o deshabilitar explcitamente la comprobacin de acceso a nivel de componente. Este atributo a nivel de ensamblado se utiliza para agregar un rol a la aplicacin. Este atributo se utiliza a nivel de componente para agregar un rol a la aplicacin y enlazarla al componente concreto.

ComponentAccessControl

SecurityRole

Desarrollo de componentes en Visual Basic .NET

23

Establecer opciones de seguridadEl siguiente ejemplo muestra cmo establecer el atributo ApplicationAccessControl a nivel de ensamblado, habilitar la seguridad para el componente Account, y crear el rol Manager, que se enlazar al componente Account: _ Public Class Account Inherits ServicedComponent ... End Class

Recuperar informacin de seguridadPodemos descubrir informacin de seguridad sobre el llamador a un componente con servicio utilizando la clase SecurityCallContext. Esta clase proporciona informacin sobre la cadena de llamadores que llevan a la llamada del mtodo actual. La propiedad esttica CurrentCall de la clase SecurityCallContext proporciona acceso a los siguientes mtodos y propiedades:Mtodo o propiedad Propiedad DirectCaller Uso Recupera informacin sobre el ltimo usuario o aplicacin de la cadena de llamadores que directamente invoc un mtodo. La propiedad devuelve una instancia de la clase SecurityIdentity que podemos utilizar para determinar informacin sobre la identidad, como AccountName. Propiedad OriginalCaller Recupera informacin sobre el primer usuario o aplicacin de la cadena de llamadores que hizo la peticin original de la accin requerida. La propiedad tambin devuelve una instancia de la clase SecurityIdentity. Mtodo IsCallerInRole Mtodo IsUserInRole Verifica si un llamador forma parte de un rol en particular; devuelve un valor Boolean. Verifica si el usuario forma parte de un rol en particular; devuelve un valor Boolean.

24

Desarrollo de componentes en Visual Basic .NET

Uso de la clase SecurityCallContextEl siguiente ejemplo muestra cmo utilizar SecurityCallContext para determinar si la seguridad est habilitada, comprobar si un llamador pertenece al rol Manager y devolver la cadena AccountName desde la propiedad OriginalCaller, que es una instancia SecurityIdentity. _ Public Class Account Inherits ServicedComponent Public Function GetDetails( ) As String If ContextUtil.IsSecurityEnabled Then With SecurityCallContext.CurrentCall If .IsCallerInRole("Manager") Then Return .OriginalCaller.AccountName End If End With End If End Function End Class

Desarrollo de componentes en Visual Basic .NET

25

Uso de otros servicios de componentesObjetivoOfrecer una descripcin del resto de servicios que proporcionan los servicios de componentes.

Otros servicios de componentes incluyen: Activacin Just-in-time Componentes en cola Propiedades compartidas Sincronizacin

Presentacin

Los servicios de componentes proporcionan otros servicios que podemos utilizar en componentes Visual Basic .NET.

Hay otros servicios de componentes que podemos utilizar desde componentes de Visual Basic .NET.

Activacin Just-in-TimeCuando se habilita la activacin Just-in-time (JIT), un objeto es instanciado automticamente cuando se invoca un mtodo en un componente con servicio (activacin), y desactivado automticamente cuando el mtodo finaliza (desactivacin). Cuando esta opcin est habilitada, un objeto no mantiene el estado entre llamadas a mtodos, y esto incrementa el rendimiento y la escalabilidad de la aplicacin. Podemos sobrecargar los mtodos Activate y Deactivate heredados de la clase ServicedComponent para realizar funcionalidad personalizada durante JIT. Si la agrupacin de objetos est habilitada, la activacin ocurre cuando un objeto existente se extrae de la agrupacin, y la desactivacin ocurre cuando el objeto se inserta de nuevo en la agrupacin. JIT se habilita automticamente si un componente es transaccional, y no puede deshabilitarse. Podemos habilitar o deshabilitar JIT manualmente para componentes no transaccionales utilizando el atributo JustInTimeActivation.

Componentes encoladosLos componentes encolados proporcionan comunicacin asncrona. Esto permite a las aplicaciones cliente enviar peticiones a componentes encolados sin esperar una respuesta. Las peticiones se graban y se envan al servidor, donde permanecen encoladas hasta que la aplicacin est lista para usar las peticiones. A continuacin, estas peticiones se reproducen y retornan a la aplicacin como si se hubieran enviado desde un cliente normal. Podemos marcar una aplicacin para que utilice colas utilizando el atributo ApplicationQueuing a nivel de ensamblado. Marcamos los componentes individuales con el atributo InterfaceQueuing.

26

Desarrollo de componentes en Visual Basic .NET

Propiedades compartidasPodemos utilizar los componentes Shared Property Manager (SPM) para compartir informacin entre mltiples objetos en el mismo proceso de aplicacin. Los componentes SPM se utilizan del mismo modo que los componentes creados en Visual Basic 6.0.

SincronizacinLas aplicaciones distribuidas pueden recibir llamadas simultneas de mltiples clientes. Gestionar estas peticiones simultneas implica una lgica de programa compleja para garantizar que se accede a los recursos de forma segura y correcta. Los servicios de componentes proporcionan este servicio automticamente para componentes que utilizan transacciones. Tambin podemos utilizar el atributo Synchronization para especificar este comportamiento.

Desarrollo de componentes en Visual Basic .NET

27

Configurar ensamblados para usar los servicios de componentesObjetivoExplicar cmo establecer atributos de los servicios de componentes a nivel de ensamblado y configurar la aplicacin.

Setting assembly attributes ApplicationName Description ApplicationActivation: library or server application AssemblyKeyFile Using Regsvcs to register and create Component Services applications Regsvcs.exe myApplication.dll Using Lazy Registration Application registered on first use by client

Presentacin

Establecer atributos de los servicios de componentes a nivel de ensamblado ayuda a definir cmo se comportar la aplicacin cuando la implantemos bajo los servicios de componentes.

Podemos especificar algunos atributos a nivel de ensamblado que proporcionan informacin cuando nuestro ensamblado se instala como una aplicacin de servicios de componentes. La informacin se almacena en el archivo AssemblyInfo.vb que forma parte de nuestro proyecto en Visual Basic .NET.Atributo de ensamblado ApplicationName Uso Si utilizamos este atributo para especificar el nombre de la aplicacin, una aplicacin de servicios de componentes con el mismo nombre cuando nuestro ensamblado sea implantado e instalado. Utilizamos este atributo para establecer el valor de la descripcin de la aplicacin de servicios de componentes cuando se implante e instale el ensamblado. Utilizamos este atributo para especificar si deseamos implementar nuestra aplicacin de servicios de componentes como una biblioteca o como una aplicacin de servidor. Los valores aceptables para este atributo son ActivationOption.Server o ActivationOption.Library. AssemblyKeyFile Utilizamos este atributo para especificar el nombre y la ubicacin del archivo que contiene el par de claves utilizado para generar un nombre compartido.

Description

ApplicationActivation

Establecer los atributos del ensambladoEl siguiente ejemplo muestra una seccin de un archivo AssemblyInfo.vb que especifica el nombre de la aplicacin, la descripcin e informacin acerca de dnde debera ser activada (es decir, en un servidor o un proceso de biblioteca).

28

Desarrollo de componentes en Visual Basic .NET

Registro del ensambladoPodemos registrar nuestro ensamblado con los servicios de componentes de modo manual o automtico. Registro manual Podemos utilizar la utilidad Regsvcs.exe para registrar manualmente nuestro ensamblado. Esta utilidad utiliza la informacin que proporcionan los atributos de nuestro ensamblado de modo que la aplicacin de servicios de componentes puede crearse con la informacin predeterminada correcta. La sintaxis bsica para utilizar Regsvcs.exe se muestra en el siguiente ejemplo:Regsvcs.exe myApplication.dll

Registro automtico Si no registramos nuestra aplicacin manualmente, el registro se producir de modo automtico cuando una aplicacin cliente intente crear una instancia de una clase gestionada que herede de la clase ServicedComponent. Todas las clases ServicedComponent de nuestro ensamblado se registrarn como parte de la aplicacin de los Servicios de componentes. Este proceso se denomina Lazy Registration.

Desarrollo de componentes en Visual Basic .NET

29

Demostracin: creacin de un componente con servicioObjetivoMostrar cmo crear un componente con servicio.

Presentacin

Esta demostracin muestra cmo crear un componente con servicio.

En esta demostracin, estudiaremos cmo crear un componente con servicio que utilice la agrupacin de objetos y cmo invocar el componente desde un cliente gestionado. Examinar la aplicacin de agrupacin de objetos 1. Abrir Microsoft Visual Studio .NET. 2. Abrir el proyecto ObjectPoolingComponent.sln que se encuentra en la carpeta ObjectPoolingComponent dentro del fichero demos11.zip. 3. Visualizar el cdigo de la clase Pooling, observando especialmente la instruccin Imports, los atributos a nivel de clase y la utilidad de cada miembro de la clase. 4. Visualizar el cdigo de la clase NoPooling, y observar que la clase es casi idntica a la clase Pooling, excepto en que no utiliza la agrupacin de objetos. 5. Visualizar el cdigo de la clase Report, y observar que el mtodo GetReport y el mtodo GetSharedProperty del mdulo modCommon. 6. Visualizar el archivo AssemblyInfo.vb file, y observar los tres primeros atributos del ensamblado que hacen referencia a las aplicaciones del componente con servicio. Crear la aplicacin del componente con servicio 1. Generar el proyecto y cerrar Visual Studio .NET. 2. Abrir Windows Explorer, e ir a la carpeta ObjectPoolingComponent\bin. 3. Hacer clic en Inicio, seleccionar Todos los programas, seleccionar Microsoft Visual Studio .NET, seleccionar Herramientas de Visual Studio .NET y hacer clic en Lnea de comandos de Visual Studio .NET.

30

Desarrollo de componentes en Visual Basic .NET

4. En la ventana de comandos, escribir Regsvcs.exe y arrastrar el archivo ObjectPoolingComponent.dll desde Windows Explorer a la lnea de comandos. 5. Ejecutar el comando. Debera aparecer un mensaje indicando que el registro se ha realizado satisfactoriamente. Examinar la aplicacin del componente con servicio 1. Abrir la consola de Servicios de Componentes y analizar la aplicacin Object Pooling. 2. Ver las propiedades de los componentes NoPool y Pool, observando la configuracin de Agrupacin de objetos en la ficha Activacin de cada componente. Examinar el funcionamiento de la prueba 3. Abrir Visual Studio .NET. 4. Abrir el proyecto TestPooling.sln que se encuentra en la carpeta ObjectPoolingComponent\TestPooling. Esta carpeta se puede encontrar dentro del fichero demos11.zip. 5. Agregar una referencia de proyecto a ObjectPoolingComponent\bin\ObjectPoolingComponent.dll. Esta fichero se puede encontrar dentro del fichero demos11.zip. 6. Ver el cdigo del formulario, examinando cada mtodo. Probar el componente 1. Ejecutar el proyecto. 2. Hacer clic en Pooling y explicar los mensajes que aparecen. 3. Hacer clic en No Pooling y explicar los mensajes que aparecen. 4. Cerrar la aplicacin. 5. Ejecutar de nuevo el proyecto y mostrar que esta vez no hay nuevos objetos creados. 6. Cerrar la aplicacin y cerrar Visual Studio .NET.

Importante Si ha ejecutado esta demostracin con anterioridad en el mismo equipo, es posible que el componente con servicio ya est instalado. Elimine la aplicacin Object Pooling de la consola de Servicios de Componentes antes de ejecutar de nuevo esta demostracin.

Desarrollo de componentes en Visual Basic .NET

31

Creacin de clases de componentesObjetivoOfrecer una descripcin de los temas tratados en esta leccin.

Arquitectura de una clase de componentes Creacin de una clase de componentes

Presentacin

Esta leccin examina las clases de componentes.

En esta leccin, aprenderemos a: Describir la arquitectura de una clase de componentes. Crear una clase de componentes.

32

Desarrollo de componentes en Visual Basic .NET

Arquitectura de una clase de componentesObjetivoDescribir la arquitectura de una clase de componentes.

Presentacin

Las clases de componentes ofrecen varias caractersticas no incluidas en las clases estndares de Visual Basic .NET.

e las e System.ComponentModel.Component C s baInterfaz IComponent

es a s las ivad C r de

Clases de componentesClases predefinidasClases personalizadas

Adems de soportar clases y estructuras, el espacio de nombres System proporciona una biblioteca de componentes diseados para facilitar el desarrollo de componentes. Cuando creamos una clase de componentes basada en la clase base ComponentModel.Component, automticamente heredamos la arquitectura bsica para nuestra clase.

Interfaz IComponentLa interfaz IComponent permite crear componentes personalizados o configurar componentes existentes como MessageQueue o Timer en el diseador visual de nuestro componente. Despus de incluir componentes existentes al nuestro (ubicar), podemos acceder a ellos desde el cdigo de nuestro componente del mismo modo que cuando estn colocados en la bandeja de componentes de un formulario Windows Forms.

Clase base ComponentModel.ComponentLa clase base ComponentModel.Component implementa automticamente la interfaz IComponent y proporciona todo el cdigo necesario para gestionar la ubicacin de componentes. Esto resulta til, ya que implementar la interfaz IComponent directamente requerira crear manualmente la funcionalidad para gestionar componentes ubicados adems de la funcionalidad para que nuestro componente pueda ser ubicado en otro componente.

Desarrollo de componentes en Visual Basic .NET

33

Caractersticas mejoradas en tiempo de diseoLa interfaz IComponent ofrece caractersticas mejoradas en tiempo de diseo. Podemos agregar nuestra clase de componentes al Cuadro de herramientas y a la bandeja de componentes de un formulario Windows Form, un formulario Web Form o cualquier otro elemento que implemente la interfaz IContainer, incluyendo otra clase de componentes. Los desarrolladores que utilicen nuestro componente pueden utilizar la ventana Propiedades para establecer las propiedades del componente del mismo modo que como lo haran para componentes del .NET Framework. Para agregar una clase de componentes compilada al Cuadro de herramientas, seguir estos pasos: 1. En el men Herramientas, hacer clic en Personalizar cuadro de herramientas. 2. En el cuadro de dilogo Personalizar cuadro de herramientas, hacer clic en la ficha Componentes de .NET Framework. 3. Busque el componente ensamblado que desea aadir. 4. Seleccione el componente de la lista que muestra los componentes compilados para agregarlo al Cuadro de herramientas.

34

Desarrollo de componentes en Visual Basic .NET

Creacin de una clase de componentesObjetivoExplicar cmo crear una clase de componentes.

1. Heredar de System.ComponentModel.Component Realizar las inicializaciones por parte del constructor Sobrecargar el mtodo Dispose 2. Agregar los componentes ubicados Utilizar elementos del Explorador de servidores o del cuadro de herramientas 3. Crear la funcionalidad requerida Propiedades, mtodos y eventos 4. Generar el ensamblado

Presentacin

Crear una clase de componentes es similar a crear un elemento de clase estndar, pero hay algunos pasos adicionales.

El procedimiento para crear una clase de componentes con Visual Basic .NET es similar al procedimiento para crear clases estndares, pero hay algunos pasos adicionales. 1. Heredar de la clase System.ComponentModel.Component. El elemento de plantilla Component Class contiene el cdigo necesario para heredar de la clase System.ComponentModel.Component, incluyendo el cdigo de constructor requerido para agregar nuestra clase de componentes a un contenedor. Agregar cualquier cdigo de inicializacin para nuestra clase de componentes como parte del proceso de construccin insertando cdigo en el mtodo Sub New anteriormente escrito. Podemos sobrecargar el mtodo Dispose de la Component Class heredada para liberar recursos antes de que se destruya la instancia de nuestro componente. 2. Agregar componentes ubicados. Si nuestra clase de componentes requiere otros componentes para realizar su propsito, podemos agregarlos a la vista de diseo arrastrndolos desde el Cuadro de herramientas o el Explorador de servidores a nuestra clase de componentes. Estos componentes pueden ser accedidos programticamente desde dentro del cdigo de nuestra clase de componentes. 3. Crear la funcionalidad requerida. Nuestra clase de componentes puede proporcionar propiedades, mtodos y eventos pblicos para permitir que el usuario de nuestro componente pueda interactuar con l tanto en tiempo de diseo como en tiempo de ejecucin. 4. Generar el ensamblado. La generacin del ensamblado permite que otros clientes gestionados puedan hacer referencia a nuestro componente.

Desarrollo de componentes en Visual Basic .NET

35

El siguiente ejemplo muestra cmo crear una clase de componentes derivada de la clase System.ComponentModel.Components. Extiende la funcionalidad de la clase Timer estndar definiendo propiedades y eventos adicionales.Imports System.ComponentModel Public Class Hourglass Inherits System.ComponentModel.Component Public Event Finished(...) Private WithEvents localTimer As System.Timers.Timer Public Sub New( ) MyBase.New( ) 'This call is required by the Component Designer. InitializeComponent( ) 'Initialize the timer for 1 minute (60000 milliseconds) localTimer = New System.Timers.Timer( ) localTimer.Enabled = False localTimer.Interval = 60000 End Sub Public Property Enabled( ) As Boolean Get Return localTimer.Enabled End Get Set(ByVal Value As Boolean) localTimer.Enabled = Value End Set End Property Private Sub localTimer_Tick(...) Handles localTimer.Elapsed 'Raise the finished event after localtimer_Tick is raised RaiseEvent Finished( ) End Sub Public Overloads Overrides Sub Dispose( ) 'Disable the localTimer object localTimer.Enabled = False localTimer.Dispose( ) MyBase.Dispose( ) End Sub End Class

Sugerencia

Comente que heredar de la clase Timer tambin producira un componente similar.

36

Desarrollo de componentes en Visual Basic .NET

Cuando examinemos el cdigo, observaremos lo siguiente: El componente se comporta como un reloj de arena que provoca un evento Finished un minuto despus de ser habilitado. El componente puede ser activado utilizando la propiedad Enabled en tiempo de diseo o en tiempo de ejecucin. Se inicializa localTimer como parte del constructor Sub New y se establece para un intervalo temporizador de 60.000 milisegundos, o un minuto. El mtodo Dispose se sobrecarga para garantizar que el objeto localTimer se elimina de forma segura.

Desarrollo de componentes en Visual Basic .NET

37

Demostracin: Creacin de un componente StopwatchObjetivoMostrar cmo crear y utilizar una clase de componentes.

Presentacin

Esta demostracin muestra cmo crear una clase de componentes stopwatch y utilizarla desde otra aplicacin.

En esta demostracin, aprenderemos cmo crear una clase de componentes que pueda ser utilizada por otro ensamblado. Examinar la clase de componentes Stopwatch 1. Abrir Visual Studio .NET. 2. Abrir el proyecto ComponentClasses.sln en la carpeta Stopwatch\Starter que se puede encontrar dentro del fichero demos11.zip. 3. Examinar la ventana de diseo de la clase de componentes Stopwatch y observar el control localTimer y sus propiedades. 4. Examinar el cdigo de la clase de componentes Stopwatch, y explicar cada miembro de la clase. Observar especialmente los atributos utilizados en las definiciones de las propiedades. Crear un icono en el Cuadro de herramientas para el componente

Sugerencia

5. Agregar una referencia para el ensamblado System.Drawing.dll. 6. Modificar la definicin de la clase como sigue: _ Public Class Stopwatch

Comentar que debe agregarse una referencia adicional para permitirnos utilizar el atributo ToolboxBitmap desde el espacio de nombres System.Drawing en los proyectos generados sobre este tipo de plantillas de proyectos.

7. En el Explorador de soluciones, arrastrar el archivo Timer01.ico y colocarlo entre las comillas de la cadena del cdigo ToolboxBitmap(""). Comentar que agregar el mapa de bits como un recurso del ensamblado puede ser una mejor opcin, ya que no depender de que el archivo de icono est disponible en la ubicacin correcta. Sin embargo, para esta demostracin, este planteamiento es aceptable. Generar el componente 1. Generar el proyecto. 2. Cerrar el proyecto.

38

Desarrollo de componentes en Visual Basic .NET

Modificar el funcionamiento de la prueba 1. Abrir el proyecto TestComponentClasses.sln de la carpeta Stopwatch\Starter\TestStopwatch que se puede encontrar dentro del fichero demos11.zip. 2. En el Cuadro de herramientas, hacer clic en la ficha General. 3. En el men Herramientas, hacer clic en Personalizar cuadro de herramientas, y clic en la ficha Componentes de .NET Framework. 4. Hacer clic en Examinar para localizar ComponentClasses.dll en la carpeta Stopwatch\Starter\bin, hacer clic en Abrir y en Aceptar. 5. En la ventana de diseo, abra Form1 y arrastre el componente Stopwatch desde el Cuadro de herramientas al formulario. 6. En la ventana de Propiedades del componente, cambiar el nombre del componente por sWatch y establecer la propiedad EnabledEvents en True. Observar la descripcin de la propiedad que proporciona el atributo Description. 7. Examinar el cdigo del formulario. Probar el componente 1. Ejecutar el proyecto, asegurndonos de que la ventana Resultados est visible en segundo plano. 2. Hacer clic en Start Stopwatch, y observar los eventos que se muestran en la ventana Resultados. Hacer clic en Tick Events para desactivar los eventos. 3. Hacer clic en Stop Stopwatch para mostrar cunto tiempo ha pasado desde que se invoc el mtodo Start en el componente Stopwatch. 4. Cerrar la aplicacin y cerrar Visual Studio .NET.

Importante Si ha ejecutado antes esta demostracin en el mismo equipo, es posible que el componente Stopwatch ya est disponible en el Cuadro de herramientas. Para asegurarse de que la demostracin funciona correctamente, restablezca el Cuadro de herramientas mediante el cuadro de dilogo Personalizar cuadro de herramientas.

Desarrollo de componentes en Visual Basic .NET

39

Creacin de controles de formularios Windows FormsObjetivoOfrecer una descripcin de los temas tratados en esta leccin.

Heredar de la clase UserControl Heredar de un control de formularios Windows Forms Proporcionar atributos de controles

Presentacin

Esta leccin examina cmo crear controles de formularios Windows Forms en Visual Basic .NET.

En versiones anteriores de Visual Basic, podemos crear controles ActiveX que pueden ser reutilizados por distintas aplicaciones cliente. En Visual Basic .NET, tambin podemos utilizar la herencia para crear controles. En esta leccin, aprenderemos a: Crear un control basado en la clase System.Windows.Forms.UserControl. Crear un control basado en un control existente Windows Forms. Agregar atributos a nuestros controles que habiliten funcionalidades avanzadas en tiempo de diseo.

40

Desarrollo de componentes en Visual Basic .NET

Heredar de la clase UserControlObjetivoExplicar cmo crear un control que herede de la clase UserControl.

Heredar de System.Windows.Forms.UserControl Agregar los controles necesarios al diseador Agregar propiedades y mtodos que correspondan a los de los controles constitutivos Agregar propiedades y mtodos adicionales No InitProperties, ReadProperties ni WriteProperties El almacenamiento de propiedades es automtico

Presentacin

En Visual Basic .NET, podemos heredar de la clase UserControl para crear el mismo tipo de controles de usuario que podemos crear en Visual Basic 6.0.

En versiones anteriores de Visual Basic, podemos crear un control nuevo y exclusivo colocando uno o ms controles existentes en un diseador UserControl. A continuacin, es posible crear propiedades, mtodos y eventos personalizados para establecer y recuperar valores para los controles contenidos. Este tipo de control es til cuando varios formularios requieren la misma composicin de controles, como formularios de direcciones o informacin de contacto.

Agregar los controles necesariosEn Visual Basic .NET, podemos crear el mismo tipo de controles de usuario si heredamos nuestro control de la clase System.Windows.Forms.UserControl, lo que resulta automtico si creamos un control utilizando el elemento de plantilla User Control. Podemos heredar de esta clase base para utilizar un diseador similar al utilizado en versiones anteriores de Visual Basic. Utilizando este mtodo, podemos: Colocar tantos controles en el diseador como sea necesario para crear nuestro propio control de usuario. Acceder a estos controles desde nuestra clase de control de usuario, ya que estn declarados como variables privadas. Agregar nuestras propias propiedades y mtodos que correspondan a las propiedades y mtodos de los controles constituyentes. Aadir propiedades, mtodos y eventos pblicos exactamente del mismo modo en que lo hacemos para una clase convencional.

Agregar propiedades y mtodosEn versiones anteriores de Visual Basic, hacemos que las propiedades sean persistentes con un objeto PropertyBag, de modo que el control conserva su configuracin entre tiempo de diseo y tiempo de ejecucin. Para ello,

Desarrollo de componentes en Visual Basic .NET

41

escribimos cdigo en los eventos ReadProperties y WriteProperties de la clase UserControl. En Visual Basic .NET, esta persistencia de informacin es automtica y no requiere cdigo adicional.

EjemploEl siguiente ejemplo muestra cmo crear un control de usuario sencillo que contiene una etiqueta y un cuadro de texto:Public Class LabelAndTextControl Inherits System.Windows.Forms.UserControl Public Property TextBoxText( ) As String Get Return TextBox1.Text End Get Set(ByVal Value As String) TextBox1.Text = Value End Set End Property Public Property LabelText( ) As String Get Return Label1.Text End Get Set(ByVal Value As String) Label1.Text = Value End Set End Property ... 'Windows Form Designer generated code End Class

Los controles TextBox1 y Label1 son variables declaradas privadas dentro del control de usuario a las que slo puede accederse utilizando las propiedades pblicas TextBoxText y LabelText.

42

Desarrollo de componentes en Visual Basic .NET

Heredar de un control existente Windows FormObjetivoExplicar cmo heredar de un control en un formulario Windows Forms.

Permite mejorar la versin de un nico control Heredar de un control System.Windows.FormsPublic Class MyTextBox Public Class MyTextBox Inherits System.Windows.Forms.TextBox Inherits System.Windows.Forms.TextBox Private strData As String Private strData As String Public Property HiddenData( ) As String Public Property HiddenData( ) As String Get Get Return strData Return strData End Get End Get Set(ByVal Value As String) Set(ByVal Value As String) strData = Value strData = Value End Set End Set End Property End Property ... ... End Class End Class

Presentacin

La herencia facilita la mejora de un control existente en Visual Basic .NET.

En versiones anteriores de Visual Basic, podemos crear versiones mejoradas de un control existente ubicando una instancia del control en el diseador UserControl. A partir de aqu, podemos crear propiedades, mtodos y eventos pblicos que correspondan a los elementos equivalentes del control constituyente, agregando elementos personalizados para crear un comportamiento mejorado. En Visual Basic .NET, podemos crear un control que herede de cualquier clase System.Windows.Forms, como la clase TextBox o Label. Como esta aproximacin utiliza herencia, no es necesario crear propiedades, mtodos y eventos pblicos que se mapeen a los del control constitutivo. Esto reduce enormemente la cantidad de cdigo necesario. nicamente debemos crear la funcionalidad adicional, segn hemos comentado en el tema anterior para los controles de usuario. El siguiente ejemplo muestra cmo crear un control que herede de SystemWindows.Forms.TextBox y agregue una propiedad pblica:Public Class MyTextBox Inherits System.Windows.Forms.TextBox Private strData As String Public Property HiddenData( ) As String Get Return strData End Get Set(ByVal Value As String) strData = Value End Set End Property ... End Class

Desarrollo de componentes en Visual Basic .NET

43

Este cdigo crea un nuevo control que hereda todas las funcionalidades de la clase TextBox y aade una propiedad denominada HiddenData.

Nota Para algunos controles existentes, podemos crear un nuevo interfaz grfico sobrecargando el mtodo OnPaint de la clase base. Sin embargo, algunos controles, como el control TextBox, son pintados directamente por Windows y no pueden ser sobrecargados.

44

Desarrollo de componentes en Visual Basic .NET

Proporcionar atributos a los controlesObjetivoExplicar cmo utilizar los atributos de los controles.

System.ComponentModel proprociona atributos a los controles A nivel de clase: DefaultProperty, DefaultEvent, ToolboxBitmap A nivel de propiedad: Category, Description, DefaultValueImports System.ComponentModel Imports System.ComponentModel __ Public Class MyTextBox Public Class MyTextBox Inherits System.Windows.Forms.UserControl Inherits System.Windows.Forms.UserControl Public Property HiddenData( ) As String Public Property HiddenData( ) As String ... ... End Property End Property ... ... End Class End Class

Presentacin

Los atributos de los controles pueden utilizarse para proporcionar informacin adicional sobre el control y sus propiedades, mtodos y eventos.

En versiones anteriores de Visual Basic, podemos utilizar el cuadro de dilogo Procedure Attributes para establecer atributos para los controles, como descripciones de las propiedades y sus categoras, que pueden ser visualizados en el Examinador de Objetos. Podemos proporcionar informacin similar en Visual Basic .NET utilizando los atributos que ofrece el espacio de nombres System.ComponentModel.

Establecer atributos a nivel de clasePodemos especificar varios atributos para el control, incluyendo DefaultProperty, DefaultEvent y ToolboxBitmap. El siguiente ejemplo muestra cmo establecer los atributos ToolboxBitmap y DefaultEvent para la clase MyTextBox: _ Public Class MyTextBox Inherits System.Windows.Forms.UserControl ... End Class

Desarrollo de componentes en Visual Basic .NET

45

Establecer atributos a nivel de propiedadPodemos especificar atributos a nivel de propiedad para propiedades pblicas, incluyendo los atributos Category, Description y DefaultValue. El siguiente ejemplo muestra cmo establecer estos atributos para la propiedad HiddenData:Imports System.ComponentModel Public Class MyTextBox Inherits System.Windows.Forms.UserControl _ Public Property HiddenData( ) As String ... End Property ... End Class

46

Desarrollo de componentes en Visual Basic .NET

Demostracin: Creacin de una caja de texto mejoradaObjetivoMostrar cmo crear un control basado en otro control existente de un formulario Windows Forms.

Presentacin

En esta demostracin, estudiaremos cmo crear un control basado en el control TextBox de Windows Forms.

En esta demostracin, estudiaremos cmo crear un control de usuario de Windows Forms basado en el control TextBox existente. Visualizar el cdigo 1. Abrir Visual Studio .NET. 2. Abrir el proyecto MyControls.sln project de la carpeta UserTextBox que se puede encontrar dentro del fichero demos11.zip. 3. Visualizar el cdigo para la clase MyTextBox y examinar todos los miembros de la clase. 4. Generar el proyecto y cerrarlo. Crear el funcionamiento de la prueba 1. Abrir el proyecto TestControl.sln de la carpeta UserTextBox\TestControl\Starter que se puede encontrar dentro del fichero demos11.zip. 2. En el Cuadro de herramientas, hacer clic en la fecha General. 3. En el men Herramientas, hacer clic en Personalizar cuadro de herramientas. En el cuadro de dilogo Personalizar cuadro de herramientas, hacer clic en la ficha Componentes de .NET Framework. 4. Hacer clic en el botn Examinar para localizar MyControls.dll en la carpeta UserTextBox\bin, hacer clic en Abrir y en Aceptar. 5. Mostrar el formulario de prueba si no est visible. 6. En el Cuadro de herramientas, arrastrar MyTextBox al formulario para crear una instancia del control MyTextBox. 7. Cambiar el nombre del control myTB, y ponerlo junto a la etiqueta MyTextBox. Establecer la propiedad Text del control en cero.

Desarrollo de componentes en Visual Basic .NET

47

8. En el controlador de eventos Click del botn Undo, elimine el comentario de la instruccin myTB.Undo. Probar el control 1. Ejecutar el proyecto. 2. Cambiar secuencialmente el valor del texto de cada cuadro de texto en base a los siguientes valores:Control TextBox MyTextBox TextBox MyTextBox TextBox MyTextBox Valor de texto One One Two Two Three Three

3. Hacer clic en el botn Undo cuatro veces y observar los cambios de cada cuadro de texto. 4. Cerrar el formulario y cerrar Visual Studio .NET.

48

Desarrollo de componentes en Visual Basic .NET

Manejo de hilos de ejecucinObjetivoOfrecer una descripcin de los temas tratados en esta leccin.

Qu es un hilo? Ventajas de mltiples hilos de ejecucin Creacin de hilos Uso de hilos Cundo utilizar el manejo de hilos

Presentacin

Visual Basic .NET permite a los desarrolladores utilizar la potencia de manejar hilos de ejecucin de un modo no disponible anteriormente en Visual Basic.

Las versiones anteriores de Visual Basic tienen un limitado soporte de manejo de hilos (threads) de ejecucin. Visual Basic .NET permite a los desarrolladores utilizar todas la potencia de los hilos cuando es necesario. Si manejamos los hilos de ejecucin correctamente, podemos mejorar el rendimiento de nuestra aplicacin y hacerla mucho ms interactiva. En esta leccin, aprenderemos a: Explicar los conceptos bsicos del manejo de hilos de ejecucin. Conocer las ventajas de incorporar mltiples hilos a nuestras aplicaciones. Crear y utilizar hilos utilizando el espacio de nombres System.Threading. Evitar algunos problemas potenciales en nuestras aplicaciones que usen mltiples hilos de ejecucin.

Aviso Esta seccin ofrece una descripcin general sobre el uso de hilos en Visual Basic .NET. ste es un tema muy complejo, y debemos estar seguros de que comprendemos completamente sus implicaciones antes de utilizar estos mtodos. Si deseamos obtener ms informacin, consultar el SDK del .NET Framework.

Desarrollo de componentes en Visual Basic .NET

49

Qu es un hilo?ObjetivoExplicar los conceptos bsicos del manejo de hilos de ejecucin.

La unidad de ejecucin que procesa la CPUTodos los procesos de una aplicacin contienen al menos un subproceso

Presentacin

Antes de examinar cmo Visual Basic .NET permite manejar hilos, es importante entender los conceptos bsicos del mismo.

Los subprocesos estn programadosParece que el equipo realiza varias tareas a la vez Cada subproceso contiene su propia pila de llamadas y almacenamiento

Proceso 1Proceso 2

Programador de subprocesos Subproc.1 Subproc. 1 2 3 CPU Subproc. 2 Subproc. 3

Sugerencia

La diapositiva asociada a este tema est animada. Hacer clic sobre ella para revelar las siguientes lecciones, mostrando el proceso iterativo del planificador de hilos: 1. Hilo 1 2. Hilo 2 3. Hilo 3 4. Hilo 1 5. Hilo 2 6. Hilo 3

Una aplicacin ejecutndose en un equipo es un proceso. Cada proceso realiza trabajo utilizando uno o ms hilos. El hilo es la unidad de ejecucin procesada por el procesador (CPU) del equipo.

Proceso de manejo de hilos de ejecucinUna CPU slo puede ejecutar un nico hilo en un instante; por ello, el planificador de hilos asigna una determinada cantidad de tiempo de CPU para cada hilo para realizar tanto trabajo como sea posible antes de permitir que otro hilo acceda a la CPU. Esta planificacin hace que parezca que el equipo est realizando varias tareas a la vez. En realidad, ocurre lo siguiente: 1. Cada hilo contiene su propia pila de llamadas y su propio almacenamiento para las variables locales. Esta informacin se guarda con el hilo y se enva a la CPU cuando el hilo est programado para procesarse. 2. Cuando acaba el tiempo, el planificador de hilos elimina el hilo la CPU y almacena la pila de llamadas y la informacin de las variables. Cuantos ms hilos se ejecuten en el sistema, con menor frecuencia se programar un hilo para ejecutarse en la CPU. Esto explica que un equipo pueda estar ejecutndose con lentitud cuando tenemos mltiples aplicaciones abiertas y funcionando a la vez.

50

Desarrollo de componentes en Visual Basic .NET

Tipos de hilosCada lenguaje de programacin puede soportar un tipo de hilo distinto: Las versiones anteriores de Visual Basic soportan el modelo de hilos apartamento (apartment). Este modelo impone algunas restricciones en los tipos de aplicaciones que estas versiones pueden crear. Una de estas restricciones es que un objeto est ligado al hilo en el que est creado, y no puede utilizarse con la agrupacin de objetos en los servicios de componentes. Sin embargo, este modelo facilita el desarrollo, ya que nos evita tratar con aspectos ms complejos como la sincronizacin. Visual Basic .NET soporta el modelo de hilos libre (free). Este modelo permite utilizar mltiples hilos de ejecucin y caractersticas como la agrupacin de objetos o continuar utilizando un nico hilo como en las aplicaciones creadas con las versiones anteriores de Visual Basic.

Desarrollo de componentes en Visual Basic .NET

51

Ventajas de mltiples hilos de ejecucinObjetivoExplicar las ventajas de tener mltiples hilos de ejecucin y el manejo de hilos libre.

Mejor respuesta de la interfaz de usuario Ejemplo: barra de estado Sin bloqueos Comunicacin asncrona Sin afinidad de hilos Los objetos no estn vinculados a un hilo

Presentacin

Tener mltiples hilos de ejecucin puede proporcionar numerosos beneficios a nuestras aplicaciones.

Una aplicacin con mltiples hilos de ejecucin tiene varias ventajas respecto a una aplicacin con un nico hilo.

Mejor respuesta de la interfaz de usuarioPodemos utilizar mltiples hilos en un nico proceso para mejorar la respuesta de la interfaz de usuario. Por ejemplo: Use hilos para operaciones lentas de procesamiento, como el uso del corrector ortogrfico o el reformateo de pginas. Estos hilos adicionales pueden disparar eventos al hilo de la interfaz de usuario principal para actualizar elementos como una barra de estado. Asignar a cada hilo un nivel de prioridad de modo que hilos especficos puedan ejecutarse con mayor prioridad que otros hilos de menor prioridad. En una aplicacin que se basa en la interaccin del usuario, deberamos ejecutar el hilo de la interfaz de usuario con un hilo de mayor prioridad.

Sin bloqueosEl bloqueo se produce porque una llamada a una aplicacin con un nico hilo debe esperar hasta que cualquier llamada previa por parte de otra aplicacin cliente haya sido completamente satisfecha antes de ejecutar cualquier otro cdigo. En aplicaciones basadas en servidor, el bloqueo ocurrir si mltiples clientes realizan peticiones simultneas de un proceso y slo est disponible un nico hilo. Aplicaciones con mltiples hilos de ejecucin pueden realizar acciones sobre diferentes hilos simultneamente (mediante la planificacin de hilos) sin esperar a que otros hilos finalicen su ejecucin actual. Esto permite a mltiples clientes ser gestionados por hilos diferentes sin bloquearse en una aplicacin basada en servidor.

52

Desarrollo de componentes en Visual Basic .NET

Comunicacin asncronaEs posible la comunicacin asncrona en una aplicacin con mltiples hilos de ejecucin porque un hilo puede realizar una peticin a otro hilo. El hilo llamador puede proseguir con otro procesamiento porque la peticin se ejecuta en un hilo separado. Puede lanzarse un evento cuando el segundo hilo finalice la ejecucin de la funcionalidad solicitada, informando al primer hilo que ha completado su trabajo.

Sin afinidad de hilosVisual Basic .NET usa el modelo de hilos libre. Este modelo no nos restringe a utilizar un objeto nicamente en el hilo donde fue inicialmente creado. Podemos crear un objeto en un hilo y pasarlo a otro hilo fcilmente. Esto mejora la escalabilidad cuando se utiliza conjuntamente con los servicios de componentes y con la agrupacin de objetos.

Desarrollo de componentes en Visual Basic .NET

53

Creacin de hilosObjetivoExplicar cmo crear y utilizar hilos.

Uso de la clase System.Threading.Thread El constructor especifica el mtodo delegado Los mtodos proporcionan control del procesamiento de hilos Las propiedades proporcionan informacin de estado y prioridades Utilizar una clase si se requieren parmetros Permitir acceso pblico a variables clase Lanzar un evento cuando finalice

Presentacin

El .NET Framework proporciona la clase System.Threading.Thread, que permite crear mltiples hilos.

El .NET Framework proporciona un modo sencillo de crear y trabajar con mltiples hilos.

Uso de la clase System.Threading.ThreadSugerenciaEl siguiente tema, Uso de hilos, ofrece un ejemplo completo del manejo de hilos.

Usar la clase Thread para crear mltiples hilos dentro de una aplicacin basada en Visual Basic .NET.

Construccin del hiloCuando se crea una instancia de Thread, el operador AddressOf pasa al constructor un delegado que representa el mtodo que debe ser ejecutado, como se muestra en el siguiente ejemplo:Dim th As New Threading.Thread(AddressOf PerformTask) ... Sub PerformTask( ) ... End Sub

54

Desarrollo de componentes en Visual Basic .NET

Mtodos de manejo de hilosLa clase Thread tambin proporciona varios mtodos para controlar el procesamiento de un hilo.Mtodo Start Abort Sleep Utilidad Comienza la ejecucin del mtodo delegado declarado en el constructor del hilo. Finaliza explcitamente un hilo de ejecucin. Pausa un hilo. Como nico parmetro, especifica el nmero de milisegundos. Si pasamos cero como parmetro, el hilo ofrece el resto de su porcin de tiempo actual. Esto es similar a DoEvents en versiones anteriores de Visual Basic. Interrumpe temporalmente la ejecucin de un hilo. Reactiva un hilo temporalmente interrumpido.

Suspend Resume

Propiedades de los hilosLa clase Thread proporciona propiedades para recuperar informacin sobre el estado del hilo y manipular la prioridad del mismo.Propiedad ThreadState Priority Utilidad Usar la propiedad ThreadState para determinar el estado actual de un hilo, como Running, Suspended o Aborted. Modificar la prioridad de un hilo estableciendo su propiedad Priority utilizando la enumeracin ThreadPriority. La enumeracin proporciona los valores siguientes: AboveNormal, BelowNormal, Highest, Lowest y Normal.

Aviso Si establecemos las prioridades de un hilo a un valor Highest, podemos afectar a otros procesos vitales del sistema reducindoles ciclos de CPU. Utilizar esta configuracin con extrema precaucin.

Creacin y prueba de hilosEl siguiente ejemplo muestra cmo crear y probar el estado de un hilo, as como cambiar su prioridad:Dim th As New Threading.Thread(AddressOf PerformTask) th.Start( ) If th.ThreadState = ThreadState.Running Then th.Priority = Threading.ThreadPriority.AboveNormal End If

Desarrollo de componentes en Visual Basic .NET

55

Uso de clases para proporcionar parmetrosSugerenciaEl siguiente tema, Uso de hilos, muestra un ejemplo de este planteamiento.

No podemos especificar un mtodo delegado que acepta argumentos en el constructor del hilo. Si nuestro procedimiento requiere informacin para realizar su accin, podemos: Usar clases para proporcionar mtodos que realicen operaciones sobre datos locales Usar propiedades pblicas o variables para suministrar los datos locales. Para usar clases y suministrar parmetros, debemos crear una instancia de la clase antes de llamar al constructor del hilo. Utilizar el operador AddressOf para pasar una referencia al mtodo de la clase como el parmetro del constructor. A continuacin podemos usar las propiedades o variables pblicas para suministrar cualquier dato requerido por el mtodo. Cuando el mtodo finalice su ejecucin, podemos lanzar un evento para informar al hilo que origin la llamada que la operacin se ha completado.

56

Desarrollo de componentes en Visual Basic .NET

Uso de hilosObjetivoExplicar un ejemplo sencillo del manejo de hilos.Class Calculate Class Calculate Public iValue As Integer Public iValue As Integer Public Event Complete(ByVal Result As Integer) Public Event Complete(ByVal Result As Integer) Public Sub LongCalculation( ) Public Sub LongCalculation( ) 'Perform a long calculation based on iValue 'Perform a long calculation based on iValue ... ... RaiseEvent Complete(iResult) 'Raise event to signal finish RaiseEvent Complete(iResult) 'Raise event to signal finish End Sub End Sub End Class End Class Sub Test( ) Sub Test( ) Dim calc As New Calculate( ) Dim calc As New Calculate( ) Dim th As New Threading.Thread(AddressOf calc.LongCalculation) Dim th As New Threading.Thread(AddressOf calc.LongCalculation) calc.iValue = 10 calc.iValue = 10 AddHandler calc.Complete, AddressOf CalcResult AddHandler calc.Complete, AddressOf CalcResult th.Start( ) th.Start( ) End Sub End Sub Sub CalcResult(ByVal Result As Integer) Sub CalcResult(ByVal Result As Integer) ... ... End Sub End Sub

Presentacin

Un vistazo a un ejemplo sencillo de manejo de hilos.

Este tpico muestra cmo preparar una clase para el manejo de hilos; crear un hilo, iniciar el hilo y realizar clculos sobre el nuevo hilo.

Preparar una clase para el manejo de hilosEl siguiente ejemplo muestra cmo crear una clase Calculate y prepararla para el manejo de hilos utilizando el evento Complete:Class Calculate Public iValue As Integer Public Event Complete(ByVal Result As Integer) Public Sub LongCalculation( ) 'Perform a long calculation based on iValue ... RaiseEvent Complete(iResult)'Raise event to signal finish End Sub End Class

Al examinar el cdigo anterior, observaremos lo siguiente: La clase proporciona una funcin LongCalculation, que se ejecutar en un hilo separado. La funcin utiliza informacin almacenada en la variable pblica entera iValue para calcular su resultado. La clase Calculate proporciona un evento Complete para notificar al hilo que realiza la llamada que el clculo ha finalizado.

Desarrollo de componentes en Visual Basic .NET

57

Creacin y uso de un hiloEl siguiente ejemplo muestra cmo crear a hilo y utilizar el manejo de hilos para realizar clculos:Sub Test( ) Dim calc As New Calculate( ) Dim th As New Threading.Thread( _ AddressOf calc.LongCalculation) calc.iValue = 10 AddHandler calc.Complete, AddressOf CalcResult th.Start( ) End Sub Sub CalcResult(ByVal Result As Integer) 'Perform appropriate action when calculation is finished ... End Sub

Al examinar este cdigo, observamos lo siguiente: La subrutina Test instancia un objeto Calculate y especifica el delegado LongCalculation en el constructor Thread. Se asigna un valor a la variable iValue para su uso por parte de la funcin Se crea un gestor de eventos para detectar la finalizacin del clculo. El mtodo Start se invoca en el hilo separado para comenzar el proceso de clculo.

58

Desarrollo de componentes en Visual Basic .NET

Cundo utilizar el manejo de hilosObjetivoExplicar algunos de los problemas potenciales causados por el manejo de mltiples hilos de ejecucin.

Utilizar los subprocesos con precaucin El uso de ms subprocesos requiere ms recursos del sistema Sincronizar el acceso a recursos compartidos Evitar que dos subprocesos accedan simultneamente a datos compartidos Utilizar la instruccin SyncLock para bloquear secciones de cdigoSub Worker( ) Sub Worker( ) SyncLock(theData) 'Lock this object variable SyncLock(theData) 'Lock this object variable theData.id = iValue theData.id = iValue 'Perform some lengthy action 'Perform some lengthy action iValue = theData.id iValue = theData.id End SyncLock 'Unlock the object variable End SyncLock 'Unlock the object variable End Sub End Sub

Presentacin

Usar mltiples hilos requiere tener presente el uso de los recursos.

Sugerencia

Apunte que el uso incorrecto de los hilos puede tener serias consecuencias.

Utilizar mltiples hilos es un concepto de programacin til en el desarrollo empresarial; sin embargo, el uso inapropiado de los hilos puede causar problemas de rendimiento, crear datos inconsistentes y otros errores.

Recursos del sistemaLos hilos consumen memoria y otros recursos valiosos, como tiempo de proceso de la CPU. Si nuestra aplicacin crea mltiples hilos, puede hacerlo a expensas de otras aplicaciones u otros hilos dentro de nuestro propio proceso. Cuantos ms hilos creemos, mayor ser el retardo entre las porciones de tiempo de CPU para cada hilo. Si todas las aplicaciones creasen un nmero excesivo de hilos y los utilizasen constantemente, el sistema dedicara la mayor parte de su tiempo intercambiando hilos en la CPU, puesto que el propio planificador de hilos requiere que la CPU se encargue de la lgica de intercambio.

Recursos compartidosSi mltiples hilos necesitan acceder a la misma informacin al mismo tiempo, puede producirse un problema de concurrencia. Dos hilos accediendo a un recurso global compartido pueden generar resultados inconsistentes si otros hilos han alterado los datos. He aqu un ejemplo de una situacin en la que esto puede suceder: El hilo A actualiza un valor en un recurso compartido como un entero, estableciendo el valor a 10 antes de realizar alguna accin de larga duracin. El hilo B actualiza el mismo valor entero a 15 durante la duracin de la accin de larga duracin del hilo A. Cuando se completa esta accin, el hilo A puede leer de nuevo el valor entero del recurso cuyo valor es ahora 15.

Desarrollo de componentes en Visual Basic .NET

59

Sincronizar recursos compartidosPodemos evitar resultados inconsistentes bloqueando el recurso entre el tiempo en que se establece inicialmente el valor y el tiempo que se lee de nuevo. Podemos utilizar la sentencia SyncLock para bloquear un tipo referencia como una clase interface, mdulo, cadena o delegado. El siguiente ejemplo define un recurso compartido denominado SharedReference que expone una variable entera. La clase ThreadObj define el mtodo que ser ejecutado por diferentes hilos. Este mtodo utiliza la sentencia SyncLock para bloquear el objeto del recurso compartido mientras est en uso. El cdigo del mdulo muestra cmo podemos probar este comportamiento creando dos hilos y dos objetos y a continuacin iniciar ambos hilos de forma consecutiva.

60

Desarrollo de componentes en Visual Basic .NETImports System.Threading 'Shared data Public Class SharedReference Public Id As Integer End Class 'Class for running on other threads Public Class ThreadObj Private sr As SharedReference Private Count As Integer 'Constructor with reference and Id Public Sub New(ByRef sharedRef As SharedReference, ByVal ID As Integer) sr = sharedRef Count = ID End Sub 'Actual worker method Public Sub RunMethod( ) SyncLock (sr) 'Lock sr object sr.Id = Count 'Execute lengthy code 'sr.Id could have changed without SyncLock Count = sr.Id End SyncLock 'Release sr object lock End Sub End Class Module MainModule Sub Main( ) 'Create shared data object Dim sr As New SharedReference( ) 'Create two worker objects Dim worker1 As New ThreadObj(sr, 1) Dim worker2 As New ThreadObj(sr, 2) 'Create two threads Dim t1 As New Thread(AddressOf worker1.RunMethod) Dim t2 As New Thread(AddressOf worker2.RunMethod) 'Start both threads t1.Start( ) t2.Start( ) End Sub End Module

_

Desarrollo de componentes en Visual Basic .NET

61

Demostracin: Uso de la instruccin SyncLockObjetivoMostrar cmo sincronizar recursos compartidos usando la sentencia SyncLock.

Presentacin

Esta demostracin muestra cmo utilizar la sentencia SyncLock para sincronizar un recurso compartido.

Informacin

Los hilos en esta demostracin pueden no ejecutarse en el orden en que han sido lanzados, de modo que nuestros resultados pueden no ser estrictamente los mismos.

En esta demostracin, aprenderemos cmo usar la sentencia SyncLock cuando utilicemos mltiples hilos en una aplicacin creada en Visual Basic .NET. Para examinar la aplicacin de agrupacin de objetos 1. Abrir Visual Studio .NET. 2. Abrir el proyecto ThreadingDemo.sln de la carpeta ThreadingDemo que se puede encontrar dentro del fichero demos11.zip. 3. Examinar el cdigo del formulario frmThreading, explicando brevemente cada miembro. 4. Examinar el cdigo de la clase ThreadObj, explicando brevemente cada miembro. Para probar la aplicacin 1. Ejecutar el proyecto. 2. Hacer clic en el botn Without SyncLock y observar que los resultados no concuerdan con los esperados. 3. Hacer clic en el botn With SyncLock y observar que los resultados coinciden correctamente con los esperados. 4. Salir de la aplicacin. 5. Examinar de nuevo el cdigo WithSyncLock dentro de la clase ThreadObj, clarificando el uso de la sentencia SyncLock que produce los resultados correctos. 6. Salir de Visual Studio .NET.