domingo, 16 de mayo de 2010

Ejecutando Hilos, comparativa Java y C#

crab-icon javacrab-icon ball c# Hoy en The Code Crab vamos a ver como se ejecutan hilos, comparando el código en C# para ello con el código en Java. No obstante, no vamos a profundizar mucho en el tema, para mas información consultad las siguientes fuentes:

Pues sin mas preámbulos, empecemos con C#.

Ejecutar un metodo en un hilo paralelo es muy sencillo. Lo primero es que no se nos debe olvidar la instrucción using: “using System.Threading;”. Una vez tenemos el using definido correctamente debemos hacer el método que queremos que se ejecute en un hilo separado. No tiene por que ir en una clase separada, ni llevar nada especial, simplemente un método normal y corriente:

 public void HelloThread()
{
while (true)
{
Console.WriteLine("Hola desde el hilo " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(300);
}
}


Tras esto definiremos e invocaremos los hilos. Puede ser en cualquier método que se ejecute que tenga acceso al método que acabamos de definir. En mi caso, estoy haciendo un programa simple de ejemplo así que pondré el código en el constructor:




public Program()
{
//Creamos y lanzamos un hilo
Thread thr1 = new Thread(HelloThread);
thr1.Start();
//Creamos y lanzamos un segundo hilo
Thread thr2 = new Thread(HelloThread);
thr2.Start();
//Esperamos 5 segundos a que hagan cosas
Thread.Sleep(5000);
//Cerramos el primer hilo
thr1.Abort();
//Join une el hilo con el principal, haciendo así que se espere a que termine ordenadamente
thr1.Join();
//Cerramos y esperamos por el segundo hilo
thr2.Abort();
thr2.Join();
Console.WriteLine("Programa terminado ordenadamente");
}


Compilamos, ejecutamos, y … tachaaaaaaaaaan, funciona!



hilos1



Ha sido fácil, ¿verdad? Mucho, diría yo. Ahora veremos como seria hacer en Java este mismo programa.



Lo primero que tenemos que hacer es crear una clase que herede de Thread, implementando el método run, donde habrá que poner la lógica del hilo:



public class ThreadClass extends Thread {
private boolean thrbool = true;
public void run(){
//Repetimos el bucle hasta que thrbool este puesto a false
while(thrbool){
System.out.println("Hello from thread "+super.getId());
//Hay que hacer try catch para poder usar thread.sleep()
try{
Thread.sleep(300);
}catch(Exception e){}
}
}
//Metodo para poner thrbool a false
//Se podria utilizar el metodo .stop para forzar a cerrarse el hilo
//Pero esta deprecated, asi que mejor terminarlo todo ordenadamente
public void stopThread(){
thrbool = false;
}
}


Tras esto debemos hacer una clase principal que instancie los hilos:



public class MainClass{
public static void main(String args[]){
//Creamos y arrancamos 2 hilos diferentes
ThreadClass thr1 = new ThreadClass();
ThreadClass thr2 = new ThreadClass();
thr1.start();
thr2.start();
try{
Thread.sleep(5000);
}catch(Exception e){}
//Hacemos que se cierren ordenadamente.
thr1.stopThread();
thr2.stopThread();
}
}


Tenemos el método stop() equivalente a Abort() de C#, pero esta deprecated, así que deberíamos crear nuestro propio método para cerrar el hilo. Tras esto ya tenemos nuestro programa funcionando con diferentes hilos.



hilos2


EDIT: Dado que Java no permite herencia multiple, el uso de la clase base Thread no esta aconsejado, puesto que si queremos utilizar en otro hilo una clase que ya hereda de algo no podriamos. La solución a esto es implementar la interfaz Runnable, siendo por lo demas exactamente igual que heredar de Thread.

¿Que os ha parecido? Siendo sincero, es bastante fácil de hacer en ambos lenguajes, pero definitivamente en caso de tener que escoger definitivamente es mas fácil en C#, pues lo mas intuitivo es lanzar un método cualquiera en un hilo distinto, sin necesidad de crear una clase a parte. Así que esa es mi conclusión. ¡¡Hasta otra y sed buenos cangrejos!! image

domingo, 9 de mayo de 2010

Guía simple: Drag-and-Drop en Windows Forms

crab-icon ball c#

Hoy en The Code Crab vamos a empezar a picar un poco de código, que siendo un blog de programación como que ya va tocando. Vamos a implementar Drag-and-Drop paso a paso, de forma sencilla con un pequeño ejemplo que os podréis descargar, pero no será nada difícil añadirlo a vuestro programas grandes.

Drag-and-Drop es una propiedad que tienen algunas interfaces graficas que permite mover objetos de un lugar a otro tan solo arrastrándolos con el ratón.

En mi caso utilizare visual studio 2010, pero esto funciona en cualquier versión de VS sin ningún problema (os dará problemas los archivos de solución quizás, pero el código en principio no). Con esto abrimos el VS, creamos un nuevo proyecto (Aplicación de windows forms en c#) y creamos una interfaz grafica simple para el ejemplo, que constara de dos listBox, aunque con un par de transformaciones el código debería funcionar sin muchos problemas para otros contenedores similares.

elefantes1Es importante que busquéis en las propiedades de los listBox la propiedad enableDrop y que la pongáis a True, sin esto el programa no funcionara. Después de esto nos metemos a modificar el código (Ver->Código)

Aquí tendremos que crear varios métodos para hacer funcionar el Drag-and-Drop. Necesitaremos dos métodos para poder coger objetos de un listBox y otros dos para poder soltar objetos en un listBox. Como queremos que se pueda cojer objetos de ambos vamos a implementar los 4 métodos una vez para cada listBox. No los repetiré por aquí pero si tenéis alguna duda podéis consultar el código que hay al final.

El primer método se llama Mouse Down, y es el evento que se dispara al pulsar sobre un elemento del listBox. Hace falta para poder sacar objetos de un componente.



///
/// Evento disparado cuando se pincha sobre un objeto de un listBox, se empieza el drag and drop
///

private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
int indexOfItem = listBox1.IndexFromPoint(e.X, e.Y);
//se almacena la posición donde esta colocado el objeto que vamos a mover
if (indexOfItem >= 0 && indexOfItem < listBox1.Items.Count)
{
//Escojemos que tipo de Drag and Drop queremos. Mi consejo es usar Copia aunque quieras mover, y quitar los objetos
//manualmente una vez que se pose el objeto, así evitaremos que si el usuario suelta el objeto fuera de un listBox,
//este se pierda.
listBox1.DoDragDrop(listBox1.Items[indexOfItem], DragDropEffects.Copy);
}
}


El siguiente método se dispara cuando se suelta un objeto en el mismo componente que se cogió, provocando así una reorganización. Se llama DragOver


 
///
/// Evento disparado al soltar un objeto en el mismo sitio donde se ha cojido
///

private void listBox1_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{

indice =
listBox1.IndexFromPoint(listBox1.PointToClient(new Point(e.X, e.Y)));
//Cambiamos el objeto seleccionado de posición, en funcion de donde se suelte
listBox1.SelectedIndex = indice;
}


Con esto concluyen los eventos para cojer objetos de un listBox. Ahora vamos con los necesarios para soltar un objeto en un componente, empezamos con DragDrop, evento que se dispara al soltar un objeto en un listBox



///
/// Evento disparado al soltar un objeto en un listBox distinto al que se cojio
///

private void listBox1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
//Podemos cambiar el formato en funcion del objeto que tengamos en listBox.Items, pero hay que tener cuidado
//por que aunque items acepte cualquier objeto, no hay formatos de Drag and Drop para todo.
listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));
if (indice >= 0 && indice < listBox1.Items.Count)
{
//Si se solto en la parte alta se pone el objeto donde corresponde
listBox1.Items.Insert(indice, e.Data.GetData(DataFormats.Text));
}
else
{
//Sino se pone en el fondo
listBox1.Items.Add(e.Data.GetData(DataFormats.Text));
}
//quitamos el objeto en el listBox2, para conseguir manualmente el efecto mover (explicado anteriormente)
listBox2.Items.Remove(e.Data.GetData(DataFormats.Text));
}


Y por ultimo hacemos un método mas, DragEnter, disparando cuando se entra con el ratón a un listBox arrastrando un objeto




/// Evento disparado al arrastrar un objeto dentro del listBox
///
public void listBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{

// Cambiamos el cursor del raton para indicar que el objeto arrastrado se puede soltar aquí
e.Effect = DragDropEffects.Copy;

}


Para que nuestro programa funcione bien debemos tener estos métodos 2 veces, uno para listBox1 y otro para listBox2, con cuidado de cambiar las referencias a estos. Tras esto solo nos queda añadir los eventos a las listBox, que lo haremos en el constructor de la clase, después de la llamada al método InitializeComponent();



//No hay que olvidarse de agregar todos los metodos que hicimos o no servira de nada
listBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(listBox1_MouseDown);
listBox1.DragOver += new System.Windows.Forms.DragEventHandler(listBox1_DragOver);
listBox1.DragDrop += new System.Windows.Forms.DragEventHandler(listBox1_DragDrop);
listBox1.DragEnter += new System.Windows.Forms.DragEventHandler(listBox1_DragEnter);

listBox2.MouseDown += new System.Windows.Forms.MouseEventHandler(listBox2_MouseDown);
listBox2.DragOver += new System.Windows.Forms.DragEventHandler(listBox2_DragOver);
listBox2.DragDrop += new System.Windows.Forms.DragEventHandler(listBox2_DragDrop);
listBox2.DragEnter += new System.Windows.Forms.DragEventHandler(listBox2_DragEnter);


Y voila, tras todo esto ya tenemos nuestro programa funcionando con Drag-and-Drop. ¿No ha sido tan difícil, no?



elefantes2Podéis descargar aquí el código fuente en caso de que os halla quedado alguna duda: http://www.megaupload.com/?d=GM4O9V65



Pues eso es todo por hoy, muchas gracias por leerme y ¡Sed buenos cangrejos!565

sábado, 8 de mayo de 2010

Utilizando librerías dll desde C++

crab-icon cpp

Bueno, aquí vamos con mi primer post, y para ir a contracorriente no vamos a empezar precisamente con algo fácil. Toca manejarse con C++, ese lenguaje maligno que tiene la habilidad en convertir lo sencillo en complicado (No es mi lenguaje favorito como habréis adivinado).

Pues en este post vamos a aprender como utilizar desde C++ una librería de linkado dinámico, mas conocidas como dlls. En cualquier otro lenguaje hacer esto es el pan de cada día, por ejemplo en C# basta con ir al apartado referencias, click derecho, agregar referencia y ya está. Sin embargo en C++ no es tan sencillo.

Para este ejemplo utilizaremos Visual Studio 2010, que esta nuevito y recién salido del horno, y no os preocupes si usáis una versión anterior que explicare las diferencias. Y para los aventados, se que utilizar una dll compilando desde línea de comandos no es nada difícil, pero tengo la extraña manía de utilizar IDEs (Lo se, soy terrible).

Bueno, pues para empezar, por algún motivo C++ no solo utiliza el archivo dll como otros lenguajes, necesitamos el archivo lib asociado y además los archivos .h de todas las clases que compone el dll. Sabiendo esto, creamos nuestro proyecto en Visual Studio, en caso de que no lo tengamos ya y vamos a la carpeta del proyecto. Para tener a mano todo esto que necesitamos crearemos aquí dos carpetas, import y lib, y metemos los archivos .h de la libreria en import y el archivo .lib en la carpeta lib.

shot1¿Y que hacemos con el archivo dll? Pues la mejor opción será meterlo en una carpeta donde el Linker no tenga problemas para encontrarlo, la mejor opción es  C:\Windows\System32 donde se encuentran los dll que utilizan otros programas.

shot2 Tras esto abrimos el Visual Studio, y una vez abrimos el proyecto, vamos a Herramientas->Opciones (Tools->Options en ingles) y aquí en proyectos y soluciones buscamos Directorios de VC++(VC++ Directories):

shot3 Ups, ¿Que es esto? Me explicare. Aquí podremos encontrar las opciones de configuración de directorios en versiones mas antiguas de VS, pero por algún motivo en VS 2010 nos encontramos con esto. Puedes pulsar ? todo lo que quieras que no sale ninguna ayuda, y la hoja de propiedades que menciona, yo personalmente no la encuentro por ningún lado. ¿Donde esta esto entonces?

En el explorador de soluciones, hacemos click derecho en el proyecto y entramos en propiedades, y ahí lo encontramos (¿Que sentido tiene quitar una cosa para dejarla en otro sitio? Aunque no tenia sentido quitarla para empezar, en fin…):

shot4Aquí en  Include Directories y en Library Directories añadimos nuestras carpetas Include y lib respectivamente, separándolas de lo que ya hay por ; y intentando no cargarnos nada.

Tras esto buscamos en la misma pantalla Vinculador->Entrada(Linker->Input):

shot5Aquí añadimos en Dependencias Adicionales(Aditional Depencences) el nombre de nuestro archivo .lib (solo el archivo, sin ruta) y una vez mas separándolo con ; y con cuidado de no cargarnos nada. Le damos a aceptar y ¡Voila! Si todo ha ido bien nuestro programa ya debería compilar y ejecutar (¡No os olvidéis de poner los include!)

shot6¿Conclusiones? Pues yo personalmente creo que esto es algo básico que debería ser muchísimo mas sencillo, y aunque explicado parezca hasta evidente os reto a intentar esto solos sin seguir ningún tutorial (Incluso podéis probar a buscar en google, que lo que yo me encontré no hizo mas que liarme).

En cuanto a lo de el Visual Studio 2010 de quitar una pantalla de configuración, cambiarla por una hoja de propiedades aparentemente inexistente y sin embargo dejar la pantalla de configuración si se accede desde otro sitio… En fin, corramos un estúpido velo, lo dejare a vuestro criterio.

Un saludo, y ¡Sed buenos cangrejos! emoti-crab5

Etiquetas de Technorati: ,,,,

jueves, 6 de mayo de 2010

Hello World


Últimamente me he tenido que enfrentar a serios problemas en cuanto a la programación, el principal de ellos el desarrollo de mi proyecto de fin de carrera.

Con esto me he dado cuenta de la cantidad de cosas que están mal documentadas en cuanto a la programación: Apis insuficiente, blogs con pocos detalles y hablando de versiones de lenguajes realmente atrasadas y posts en foros que hablan y hablan pero no resuelven la duda que preguntan al principio.

Tras esto me dio por pensar que quizás debiera poner mi grano de arena al mundo de la programación haciendo mi propio blog dedicado a este tema, y actualizarlo con los problemas que me hayan encontrado los cuales sean difíciles de encontrar por internet.

En este blog se trataran varios lenguajes de programación, pero probablemente me centre en C# y Java, viendo ocasionalmente cosas de C++, C, Ruby y Python. Si con mis posts consigo ayudar a alguien, mi blog habrá cumplido su cometido. ¡Hola Mundo!