viernes, 27 de febrero de 2015
martes, 17 de febrero de 2015
Threads y Delegados en C#
Threads y Delegados en C#
Threads y Delegados en C#
Introducción
En éste articulo de tipo tutorial se explicará a un nivel digerible para estudiantes o programadores con conocimientos no muy avanzados sobre programación en language C#, el úso de Threads y Delegados. Prácticamente, explicando cuál es la idea de utilizar estas herramientas y algunos problemas o causas que ameritan utilizarlas.
El énfasis de este articulo es llevar a la práctica este tema, con un simple ejemplo en una aplicación de Windows Forms, con explicaciones en partes especificas del código que necesita quedar perfectamente claro para la comprensión de ejercicio y por ende el tema.
El ejemplo consiste en un programa que intenta interactuar (modificar) un Control de Windows Forms utilizando Threads. Una simple animación interactiva utilizando estos Controles (Button) que son parte de la idea principal del ejercicio.
Definiciones
Vamos explicando primero que estas 2 herramientas "Threads" y "Delegados":
Cuando se programa una simple aplicación en Consola o Windows Forms, la misma es un solo proceso por si misma, la cuál contiene métodos/funciones que son ejecutados de manera secuencial, esto significa que es necesario la finalización de uno para que otro método inicie, continue o concluya. todo esto es parte de un "Main thread" o hilo de proceso principal.
Si se desea ejecutar mas de un método a la vez, es necesario implementar otro hilo (thread) de manera independiente al principal. Al final cada thread ejecutará su propio código "al mismo tiempo" que otro.
Un delegado es un tipo que se define con una “firma” de un método, es decir que al crearlo/declararlo se especifica con que tipo de método va trabajar, si es un método "void" o devuelve algún valor, y si recibe argumentos. Cuando se instancía un delegado a partir de su definición, se le asigna almenos un método
En éste caso, nuestro delegado se va encargar de ejecutar algunas funciones que normalmente causan problemas a la hora de utilizar Controles de Windows Forms con Threads. Un delegado simplemente es invocado para realizer su(s) métodos que le fueron asignados. También se puede encargar de "event handling", que en éste tipo de aplicaciones no es mas que eventos y delegados.
Aplicación
Vamos a crear en Visual Studio un proyecto de WindowsForms y rapidamente arrogar 3 Controles por el momento, un PictureBox, Button y TextBox:
Ahora vamos a hacer un poco de limpieza antes de continuar, renombrar los controles y asignarle una imagen de fondo al PictureBox para darle un poco de sentido gráfico al programa, para eso, puse un muñeco como imágen:
El siguiente código sera simplemente para mover el PictureBox através del Form:<br />
private void Mover()<br />
{
while (PBx_mono.Location.X + PBx_mono.Width < this.Width)
{
PBx_mono.Location = new Point(PBx_mono.Location.X + 10, PBx_Location.Y);
Thread.Sleep(200); // Este cambio de posición se hará 5 veces por Segundo.
}
}
Si asignamos este método al evento Click del botón que tenemos creado, corremos el programa y tratamos de escribir algo de texto en el TextBox, no será posible hacerlo o almenos ver lo que escribamos en el momento, ya que el Thread principal está "ocupado" haciendo el método "Mover()", al finalizar esto, entonces podremos ver el texto que escribamos. ES IMPORTANTE DAR CLICK AL TEXTBOX PARA ENFOCARLO ANTES DE ESCRIBIR AUNQUE NO SEA POSIBLE VER TEXTO:
Esa es una posible razón por que se requiera utilizer un 2do thread.
Hay que crear uno simplemente declarando como un objeto (no se olvide de poner "using System.Threading"
:
Thread Segundo_thread;
private void Form1_Load(object sender, EventArgs e)
{
Segundo_thread = new Thread(Mover);
// Será el trabajo de este thread realizer el movimiento del PictureBox
}
private void Button_iniciar_Click(object sender, EventArgs e)
{
Segundo_thread.Start()
}
Ahora vamos a iniciar el programa y dar click en el botón a ver que sucede:
No es possible alterar de esa manera un Control (en este caso un PictureBox) desde otro thread que no sea el principal, por motivos de seguridad. Aqui es dónde entran los delegados.
Ya se explicó en la introducción que son y para que sirven, entonces vamos a declarar uno y asignarle la tarea de mover el PictureBox, solo sería la linea que indica la nueva posición de éste.
Además, el PictureBox por si mismo puede invocar un delegado, debido a que es con el con quién queremos trabajar, tenemos que invocar el delegado apartir del método Invoke() del PictureBox
El código quedaría asi:
Si ejecutamos el programa, el resultado seria el siguiente:
El resultado es exitoso. Hemos aprendido de un ejemplo muy simple de threads y delegados.
Gracias por tu atención, espero te haya servido el tutorial.
En éste articulo de tipo tutorial se explicará a un nivel digerible para estudiantes o programadores con conocimientos no muy avanzados sobre programación en language C#, el úso de Threads y Delegados. Prácticamente, explicando cuál es la idea de utilizar estas herramientas y algunos problemas o causas que ameritan utilizarlas.
El énfasis de este articulo es llevar a la práctica este tema, con un simple ejemplo en una aplicación de Windows Forms, con explicaciones en partes especificas del código que necesita quedar perfectamente claro para la comprensión de ejercicio y por ende el tema.
El ejemplo consiste en un programa que intenta interactuar (modificar) un Control de Windows Forms utilizando Threads. Una simple animación interactiva utilizando estos Controles (Button) que son parte de la idea principal del ejercicio.
Definiciones
Vamos explicando primero que estas 2 herramientas "Threads" y "Delegados":
Cuando se programa una simple aplicación en Consola o Windows Forms, la misma es un solo proceso por si misma, la cuál contiene métodos/funciones que son ejecutados de manera secuencial, esto significa que es necesario la finalización de uno para que otro método inicie, continue o concluya. todo esto es parte de un "Main thread" o hilo de proceso principal.
Si se desea ejecutar mas de un método a la vez, es necesario implementar otro hilo (thread) de manera independiente al principal. Al final cada thread ejecutará su propio código "al mismo tiempo" que otro.
Un delegado es un tipo que se define con una “firma” de un método, es decir que al crearlo/declararlo se especifica con que tipo de método va trabajar, si es un método "void" o devuelve algún valor, y si recibe argumentos. Cuando se instancía un delegado a partir de su definición, se le asigna almenos un método
En éste caso, nuestro delegado se va encargar de ejecutar algunas funciones que normalmente causan problemas a la hora de utilizar Controles de Windows Forms con Threads. Un delegado simplemente es invocado para realizer su(s) métodos que le fueron asignados. También se puede encargar de "event handling", que en éste tipo de aplicaciones no es mas que eventos y delegados.
Aplicación
Vamos a crear en Visual Studio un proyecto de WindowsForms y rapidamente arrogar 3 Controles por el momento, un PictureBox, Button y TextBox:
Ahora vamos a hacer un poco de limpieza antes de continuar, renombrar los controles y asignarle una imagen de fondo al PictureBox para darle un poco de sentido gráfico al programa, para eso, puse un muñeco como imágen:
El siguiente código sera simplemente para mover el PictureBox através del Form:<br />
private void Mover()<br />
{
while (PBx_mono.Location.X + PBx_mono.Width < this.Width)
{
PBx_mono.Location = new Point(PBx_mono.Location.X + 10, PBx_Location.Y);
Thread.Sleep(200); // Este cambio de posición se hará 5 veces por Segundo.
}
}
Si asignamos este método al evento Click del botón que tenemos creado, corremos el programa y tratamos de escribir algo de texto en el TextBox, no será posible hacerlo o almenos ver lo que escribamos en el momento, ya que el Thread principal está "ocupado" haciendo el método "Mover()", al finalizar esto, entonces podremos ver el texto que escribamos. ES IMPORTANTE DAR CLICK AL TEXTBOX PARA ENFOCARLO ANTES DE ESCRIBIR AUNQUE NO SEA POSIBLE VER TEXTO:
Esa es una posible razón por que se requiera utilizer un 2do thread.
Hay que crear uno simplemente declarando como un objeto (no se olvide de poner "using System.Threading"
Thread Segundo_thread;
private void Form1_Load(object sender, EventArgs e)
{
Segundo_thread = new Thread(Mover);
// Será el trabajo de este thread realizer el movimiento del PictureBox
}
private void Button_iniciar_Click(object sender, EventArgs e)
{
Segundo_thread.Start()
}
Ahora vamos a iniciar el programa y dar click en el botón a ver que sucede:
No es possible alterar de esa manera un Control (en este caso un PictureBox) desde otro thread que no sea el principal, por motivos de seguridad. Aqui es dónde entran los delegados.
Ya se explicó en la introducción que son y para que sirven, entonces vamos a declarar uno y asignarle la tarea de mover el PictureBox, solo sería la linea que indica la nueva posición de éste.
Además, el PictureBox por si mismo puede invocar un delegado, debido a que es con el con quién queremos trabajar, tenemos que invocar el delegado apartir del método Invoke() del PictureBox
El código quedaría asi:
Si ejecutamos el programa, el resultado seria el siguiente:
El resultado es exitoso. Hemos aprendido de un ejemplo muy simple de threads y delegados.
Gracias por tu atención, espero te haya servido el tutorial.
Thread Delegate Invoke y creacion de Objetos a Mano
thread delegate invoke
Espacio de nombres: System.Windows.Forms
Ensamblado: System.Windows.Forms (en System.Windows.Forms.dll)
Valor devuelto desde el delegado al que se ha invocado o null si el delegado no devuelve ningún valor.
Control.Invoke (Método) (Delegate)
.NET Framework 4.5
Ejecuta el delegado especificado en el subproceso que posee el identificador de ventana subyacente del control.
Espacio de nombres: System.Windows.Forms
Ensamblado: System.Windows.Forms (en System.Windows.Forms.dll)
Parámetros
- method
- Tipo: System.Delegate
Delegado que contiene un método al que se va a llamar en el contexto del subproceso del control.
Valor devuelto
Tipo: System.ObjectValor devuelto desde el delegado al que se ha invocado o null si el delegado no devuelve ningún valor.
Los delegados son similares a los punteros a funciones de los lenguajes C o C++. Los delegados encapsulan una referencia a un método dentro de un objeto delegado. El
objeto delegado se puede pasar entonces a código que llame al método al
que se ha hecho referencia y el método que hay que invocar puede ser
desconocido en tiempo de compilación. A
diferencia de los punteros a funciones de C o C++, los delegados están
orientados a objetos, tienen seguridad de tipos y son más seguros.
El método Invoke busca en la cadena principal del control hasta que encuentra un control o un formulario que tiene un identificador de ventana si el identificador de ventana subyacente del control actual no existe todavía. Si no se encuentra un identificador apropiado, el método Invoke producirá una excepción. Las excepciones generadas durante la llamada se propagarán hacia el llamador.
El delegado puede ser una instancia de EventHandler, en cuyo caso el parámetro remitente contendrá este control, y el parámetro de evento contendrá EventArgs.Empty. El delegado también puede ser una instancia de MethodInvoker o cualquier otro delegado que tome una lista de parámetros vacía. Una llamada a un delegado EventHandler o MethodInvoker será más rápida que una llamada a otro tipo de delegado.
El método Invoke busca en la cadena principal del control hasta que encuentra un control o un formulario que tiene un identificador de ventana si el identificador de ventana subyacente del control actual no existe todavía. Si no se encuentra un identificador apropiado, el método Invoke producirá una excepción. Las excepciones generadas durante la llamada se propagarán hacia el llamador.
Nota |
|---|
| Además de la propiedad InvokeRequired, en un control hay cuatro métodos que son seguros para la ejecución de subprocesos: Invoke, BeginInvoke, EndInvoke y CreateGraphics si ya se ha creado el identificador del control. La llamada a CreateGraphics antes de la creación del identificador del control en un subproceso de fondo puede producir llamadas no válidas entre subprocesos. Para el resto de las llamadas a métodos, sería conveniente utilizar uno de los métodos de invocación para calcular las referencias de la llamada al subproceso del control. |
Nota |
|---|
| Podría iniciarse una excepción si el subproceso que debe procesar el mensaje ya no está activo. |
En el ejemplo de código siguiente se muestran controles que contienen un delegado. El
delegado encapsula un método que agrega elementos al cuadro de lista y
este método se ejecuta en el subproceso que posee el identificador
subyacente del formulario. Cuando el usuario hace clic en el botón, Invoke ejecuta el delegado.
/* The following example demonstrates the 'Invoke(Delegate)' method of 'Control class. A 'ListBox' and a 'Button' control are added to a form, containing a delegate which encapsulates a method that adds items to the listbox.This function is executed on the thread that owns the underlying handle of the form. When user clicks on button the above delegate is executed using 'Invoke' method. */ using System; using System.Drawing; using System.Windows.Forms; using System.Threading; public class MyFormControl : Form { public delegate void AddListItem(); public AddListItem myDelegate; private Button myButton; private Thread myThread; private ListBox myListBox; public MyFormControl() { myButton = new Button(); myListBox = new ListBox(); myButton.Location = new Point(72, 160); myButton.Size = new Size(152, 32); myButton.TabIndex = 1; myButton.Text = "Add items in list box"; myButton.Click += new EventHandler(Button_Click); myListBox.Location = new Point(48, 32); myListBox.Name = "myListBox"; myListBox.Size = new Size(200, 95); myListBox.TabIndex = 2; ClientSize = new Size(292, 273); Controls.AddRange(new Control[] {myListBox,myButton}); Text = " 'Control_Invoke' example"; myDelegate = new AddListItem(AddListItemMethod); } static void Main() { MyFormControl myForm = new MyFormControl(); myForm.ShowDialog(); } public void AddListItemMethod() { String myItem; for(int i=1;i<6;i++) { myItem = "MyListItem" + i.ToString(); myListBox.Items.Add(myItem); myListBox.Update(); Thread.Sleep(300); } } private void Button_Click(object sender, EventArgs e) { myThread = new Thread(new ThreadStart(ThreadFunction)); myThread.Start(); } private void ThreadFunction() { MyThreadClass myThreadClassObject = new MyThreadClass(this); myThreadClassObject.Run(); } } // The following code assumes a 'ListBox' and a 'Button' control are added to a form, // containing a delegate which encapsulates a method that adds items to the listbox. public class MyThreadClass { MyFormControl myFormControl1; public MyThreadClass(MyFormControl myForm) { myFormControl1 = myForm; } public void Run() { // Execute the specified delegate on the thread that owns // 'myFormControl1' control's underlying window handle. myFormControl1.Invoke(myFormControl1.myDelegate); } }
viernes, 13 de febrero de 2015
lunes, 9 de febrero de 2015
Coniguracion Remota Sql Server
Configuracion remota sql Server.
PASOS PARA CONFIGURAR SQL SERVER 2008 PARA ADMITIR CONEXIONES REMOTAS.
Las nuevas políticas de Seguridad de Microsoft incorporan restricciones a
la hora de comenzar a usar SQL Server 2008. Los Servicios que antes
estaban habilitados por defecto, ahora no lo están, y es función del
Administrador ir habilitándolos según las necesidades de uso del mismo.
Una de las cuestiones más importantes es la de Admitir Conexiones Remotas en nuestro Servidor. A fin de habilitarlas y asegurarnos que se pueden conectar desde otros ordenadores debemos seguir unos sencillos pasos:
1. Abriremos SQL Server Management Studio, nos situamos encima de la instancia de nuestro Servidor y pulsamos botón derecho, Propiedades, seleccionamos Conexiones, nos mostrara la siguiente pantalla:
Ahora marcamos el checkbox: “Permitir conexiones remotas con este servidor” u pulsamos aceptar.
2. Vamos al Menú de Inicio > Programas > Microsoft SQL Server 2008 > Herramientas de Configuración > Administrador de Configuración de SQL Server, aparece la siguiente ventana:
Seleccionamos la Configuración de red de SQL Server y luego Protocolos de MSSQLSERVER. Como podemos observar, por defecto solo tiene habilitado el protocolo de Memoria compartida, el resto estan deshabilitados. Básicamente es el tipo de protocolo que se usa, cuando nos conectamos a SQL Server desde el mismo Servidor.
Lo que debemos hacer es habilitar los protocolos: “Canalizaciones con nombre” y “TCP/IP”. Para lo cual, pulsamos con el botón derecho del ratón encima de los mismos y pulsamos Habilitar. En las dos ocasiones nos mostrara un mensaje informándonos, que para que la nueva configuración surta efecto abra que reiniciar el Servicio de SQL Server.
Ahora nos quedará así:
3. Vamos al Menú de Inicio > Ejecutar y escribimos services.msc y le damos aceptar. De esta forma nos abrirá la Consola de Administración de Servicios. Nos desplazamos hasta el Servicio con nombre “SQL Server (MSSQLSERVER)”, nos situamos encima y pulsamos el botón derecho del ratón, seleccionando; reiniciar. Con esto aplicaremos los cambios efectuados en el paso anterior.
4. SI estamos utilizando SQL Server con nombre de instancia y sin emplear un número concreto de puerto TCP/IP, debemos habilitar el servicio SQL Server Browser, que se encuentra en la misma ventana de Servicios con el nombre de “SQL Server Browser”. Nos situamos encima y con el botón derecho del ratón pulsamos en Propiedades, o bien podemos hacer doble click, es lo mismo.
En el Tipo de Inicio, seleccionamos Automático y pulsamos Iniciar para que el Servicio arranque. Aceptar para cerrar la pantalla.
Este Servicio comporta ciertos riesgos de seguridad que deben ser considerados, pues existen otras alternativas a utilizar como configurar el Cliente de SQL Servidor con el Alias del Servidor, o utilizar la conexión incorporando el puerto de TCP/IP a usar, por defecto en SQL Server es el 1433.
5. Y por último, en caso de tener habilitado el Firewall de Windows, cosa que deberíamos tener por Seguridad, deberemos configurarlo para que los Servicios de SQL Server y SQL Browser puedan comunicarse con el exterior. Vamos a Menú de Inicio , hacemos clic en Ejecutar , escribimos firewall.cpl y pulsamos Aceptar. Nos muestra esta ventana:
Pulsamos en “Permitir un programa a través del Firewall de Windows” nos muestra:
Pulsamos en Agregar programa nos muestra la ventana:
Pulsamos en Examinar e introducimos la carpeta donde se encuentra el Servicio de SQL Server: “C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Binn” en la misma seleccionamos el programa: “sqlservr.exe” y pulsamos Aceptar. Repetimos la operación para añadir el SQL Server Browser que se encuentra en la carpeta: “C:\Program Files\Microsoft SQL Server\90\Shared”. Seleccionamos el programa: “sqlbrowser.exe” y pulsamos Aceptar. Veremos que ambas excepciones nos aparecen en la pantalla de Configuración del Firewall.
Y con esto ya tenemos configurado nuestro Servidor SQL 2008 para permitir Conexiones desde cualquier ordenador de nuestra red.
Una de las cuestiones más importantes es la de Admitir Conexiones Remotas en nuestro Servidor. A fin de habilitarlas y asegurarnos que se pueden conectar desde otros ordenadores debemos seguir unos sencillos pasos:
1. Abriremos SQL Server Management Studio, nos situamos encima de la instancia de nuestro Servidor y pulsamos botón derecho, Propiedades, seleccionamos Conexiones, nos mostrara la siguiente pantalla:
Ahora marcamos el checkbox: “Permitir conexiones remotas con este servidor” u pulsamos aceptar.
2. Vamos al Menú de Inicio > Programas > Microsoft SQL Server 2008 > Herramientas de Configuración > Administrador de Configuración de SQL Server, aparece la siguiente ventana:
Seleccionamos la Configuración de red de SQL Server y luego Protocolos de MSSQLSERVER. Como podemos observar, por defecto solo tiene habilitado el protocolo de Memoria compartida, el resto estan deshabilitados. Básicamente es el tipo de protocolo que se usa, cuando nos conectamos a SQL Server desde el mismo Servidor.
Lo que debemos hacer es habilitar los protocolos: “Canalizaciones con nombre” y “TCP/IP”. Para lo cual, pulsamos con el botón derecho del ratón encima de los mismos y pulsamos Habilitar. En las dos ocasiones nos mostrara un mensaje informándonos, que para que la nueva configuración surta efecto abra que reiniciar el Servicio de SQL Server.
Ahora nos quedará así:
3. Vamos al Menú de Inicio > Ejecutar y escribimos services.msc y le damos aceptar. De esta forma nos abrirá la Consola de Administración de Servicios. Nos desplazamos hasta el Servicio con nombre “SQL Server (MSSQLSERVER)”, nos situamos encima y pulsamos el botón derecho del ratón, seleccionando; reiniciar. Con esto aplicaremos los cambios efectuados en el paso anterior.
4. SI estamos utilizando SQL Server con nombre de instancia y sin emplear un número concreto de puerto TCP/IP, debemos habilitar el servicio SQL Server Browser, que se encuentra en la misma ventana de Servicios con el nombre de “SQL Server Browser”. Nos situamos encima y con el botón derecho del ratón pulsamos en Propiedades, o bien podemos hacer doble click, es lo mismo.
En el Tipo de Inicio, seleccionamos Automático y pulsamos Iniciar para que el Servicio arranque. Aceptar para cerrar la pantalla.
Este Servicio comporta ciertos riesgos de seguridad que deben ser considerados, pues existen otras alternativas a utilizar como configurar el Cliente de SQL Servidor con el Alias del Servidor, o utilizar la conexión incorporando el puerto de TCP/IP a usar, por defecto en SQL Server es el 1433.
5. Y por último, en caso de tener habilitado el Firewall de Windows, cosa que deberíamos tener por Seguridad, deberemos configurarlo para que los Servicios de SQL Server y SQL Browser puedan comunicarse con el exterior. Vamos a Menú de Inicio , hacemos clic en Ejecutar , escribimos firewall.cpl y pulsamos Aceptar. Nos muestra esta ventana:
Pulsamos en “Permitir un programa a través del Firewall de Windows” nos muestra:
Pulsamos en Agregar programa nos muestra la ventana:
Pulsamos en Examinar e introducimos la carpeta donde se encuentra el Servicio de SQL Server: “C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Binn” en la misma seleccionamos el programa: “sqlservr.exe” y pulsamos Aceptar. Repetimos la operación para añadir el SQL Server Browser que se encuentra en la carpeta: “C:\Program Files\Microsoft SQL Server\90\Shared”. Seleccionamos el programa: “sqlbrowser.exe” y pulsamos Aceptar. Veremos que ambas excepciones nos aparecen en la pantalla de Configuración del Firewall.
Y con esto ya tenemos configurado nuestro Servidor SQL 2008 para permitir Conexiones desde cualquier ordenador de nuestra red.
jueves, 5 de febrero de 2015
domingo, 1 de febrero de 2015
Suscribirse a:
Comentarios (Atom)
Nota






