FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
No consigo que el terminate de un thread tenga efecto!!
Hola a todos, no consigo terminar un thread!
tengo creado en un Unit una clase TThread llamado ThreadPackets que se encarga de ir sacando los paquetes que se captura en un ListView. En el método execute de dicho clase tengo algo estilo.. Código:
while (!Terminated) { //sacar paquetes } Código:
void Capturar::Funcion1() { //se abre el dispositivo //selecciona el dispositivo a sniffar miThread = new ThreadPackets(adhandle); } Código:
void Capturar::StopThreadPackets() { miThread->Terminate(); } Código:
void __fastcall TForm1::Button4Click(TObject *Sender) { Capturar *x = new Capturar(); x->StopThreadPackets(); delete x; } que estoy haciendo mal u obviando? existe otra alternativa? gracias |
#2
|
||||
|
||||
Pues el error lo tienes aquí:
Código:
void __fastcall TForm1::Button4Click(TObject *Sender) { Capturar *x = new Capturar(); x->StopThreadPackets(); delete x; } Código:
void Capturar::StopThreadPackets() { miThread->Terminate(); } La solución es que tengas controlado el puntero miThread de forma que sea una variable global de Form1, static de la clase Capturar, que lo copies al crear un elemento Capturar o que simplemente Form1 tenga un miembro de la clase Capturar ya creado de forma que no necesites crear uno nuevo para la función Button4Click. En definitiva que sepas que miThread apunta a lo que tu quieres. Saludos. Última edición por escafandra fecha: 04-03-2008 a las 23:52:39. |
#3
|
|||
|
|||
Hola de nuevo, ante todo gracias por la pronta respuesta.
Cita:
Código:
class Capturar { private: ... ThreadPackets *miThread; public: ... }; Código:
#include "Unit4.h" Y más o menos entiendo lo que has mencionado: Cita:
1. mediante un botón para empezar la captura de paquetes: Código:
void __fastcall TForm1::Button2Click(TObject *Sender) { x = new Capturar(); x->Funcion1(); //aqui dentro es donde llega el momento de capturar llama a miThread = new ThredPackets(adhandle) } void __fastcall TForm1::Button4Click(TObject *Sender) { x->StopThreadPackets(); delete snf; } Pero con esto tampoco va... y, cuando pruebo que el puntero miThread sea static en la clase Capturar y pongo en el .h: Código:
class Capturar { private: ... ThreadPackets static *miThread; public: ... }; [Linker Error] Unresolved external 'Capturar::miThread' referenced from C:\DOCUMENTS AND SETTINGS\ADMINISTRADOR\MIS DOCUMENTOS\EXESC\BONITO(1.2)\UNIT3.OBJ y sin static, me compila bien, seguramente no lo esté poniendo bien, me podeis dar más info sobre lo de poner el puntero static? |
#4
|
||||
|
||||
Bien. Yo crearía x al crear Form1 y no con un evento de botón que puede ejecutarse o no a gusto del usuario. x debe ser un miembro de Form1 creado y que se destruya en el destructor de Form1. Pon un punto de parada en miTrhead, para detectar si es tu objeto u otro el que ejecuta Terminate, (puedes controlar si un miembro de valor conocido y esperable lo tiene o no, para saber si efectivamente miThread apunta a tu tarea que se está ejecutando).
Los miembros static de una clase son un poco liosos. Deben estar declarados e inicializados al declarar la clase, pues su valor será el mismo para todos los objetos que existan de esa clase. Y sólo se pueden modificar por funciones también declaradas como static. En tu caso es preferible que x exista en todo momento para contro0lar miThread. El problema está en si quieres que exixtan varias tareas capturar ejecutandose al mismo tiempo. Esto te obliga a crear una matriz de punteros en Form1 y tener todos ellos guardados para ejecutar, en un bucle, por ejemplo x->Terminate(). ANALIZA ESTO: El hecho de que Código:
void __fastcall TForm1::Button2Click(TObject *Sender) { x = new Capturar(); x->Funcion1(); //aqui dentro es donde llega el momento de capturar llama a miThread = new ThredPackets(adhandle) } Última edición por escafandra fecha: 05-03-2008 a las 21:31:13. |
#5
|
|||
|
|||
Hola de nuevo,
Cita:
Capturar *x; //variable global void __fastcall TForm1::FormCreate(TObject *Sender) { x = new Capturar(); //crea el objeto } .. void __fastcall TForm1::Button4Click(TObject *Sender) { x->StopThreadPackets(); } void __fastcall TForm1::FormDestroy(TObject *Sender) { delete x; } vale, con esto si le doy al boton de parar sigue sin parar, pero me ha surgido una nueva duda: en la class Capturar como indiqué anteriormente tengo en el .cpp: ThreadPackets *miThread;//instancio globalmentre miThread void Capturar::Funcion1() { //se abre el dispositivo //selecciona el dispositivo a sniffar miThread = new ThreadPackets(adhandle); } y en otro método: void Capturar::StopThreadPackets() { miThread->Terminate(); } puede que no termine porque al estar en métodos diferentes son dos objetos diferentes? aunque se hayan instanciado globalmente? Cita:
gracias |
#6
|
||||
|
||||
Ahora no veo donde pones en marcha tu thread. No ejecutas Funcion1 en el código que me expones. Digo esto, porque miThtread será creado cada vez que ejecutes Funcion1 y puedes "acumular threads incontrolados".
El hecho de que sea una variable global, en principio no debe influir si la lógica de programación es correcta, aunque al estar programando orientado a objetos, no tiene sentido una variable global que sólo va a utilizar una clase y a la que no se accede desde otro punto. No se como tienes programada el Thread. Cuando utilizo threads, creo un elemento TThread desde la opción new del Builder. Me crea un prototipo de clase derivada de TThread que yo termino de definir e implementar. La función Terminate() No termina inmediatamente con el Thread, sino que lo hace tan pronto como sea posible, por lo que la lógica de programación puede influir. Sólo chekeando el valor de Thread->Terminated, sabrás que ha terminado. Para terminar inmediatamente puedes usar la API TerminateThread. Los puntos de parada los generas al colocar el cursor un una línea de código y pulsar F5. Cuando el código que se ejecuta llege a ese punto, se para y puedes comprobar valores, ejecutar paso a paso....Debugear. En definitiva: 1) Controla que tu puntero miThread apunta realmente a lo que tu quieres. 2) Ejecuta el código que tengas en la función miThread->Execute() paso a paso y comprueba que no penetras en un bucle sin fin. 3) Recuerda la API TerminateThread para terminar a la fuerza, claro que esto te puede hacer perder datos. Saludos. Última edición por escafandra fecha: 07-03-2008 a las 19:41:10. Razón: Mal funcionamiento del editor |
#7
|
|||
|
|||
Hola, creo que ya está solucionado!
he estado ejecutando con puntos de ruptura y paso a paso. puse un punto en la linea void __fastcall TForm1::Button4Click(TObject *Sender) y al darle al botón no se me paraba el código.. lo cual me hizo dudar... por tanto he creado un nuevo botón con el mismo contenido (para parar el thread) y ahora si que me para!! Vamos.. que el código estaba bien planteado, lo que ocurre es que al darle al botón no me referenciaba al código y creo que es que cuando estuve haciendo pruebas, y tuve que comentar (poner las //), del builder me salió una ventanita diciéndome que no existía tal objeto o algo así (no estoy segura) y le día a aceptar y creo que con ello abría eliminado la relación del botón con el código.. o algo así . muchas gracias de ahora en adelante tengo que usar más los puntos de ruptura. Aún así tengo otra dudilla, con el watch, se puede ver los valores de las variables en tiempo de ejecución, lo he estado probando añadiéndo diferentes variables, pero al querer ver los valores me pone: [process not accesible]?? |
#8
|
||||
|
||||
Enhorabuena.
Claro... No puedes ver las variables con el watch hasta que tu código no se está ejecutando en el ámbito de esas variables.... Saludos. Última edición por escafandra fecha: 08-03-2008 a las 23:37:42. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Conexión con BD Access que tenga contraseña | LinaC | Tablas planas | 2 | 01-02-2008 23:02:40 |
Ayuda, Problema con Application.terminate delphi .net | nethcy | .NET | 2 | 08-05-2006 05:00:54 |
Thread bendito thread...se me pierde la ventana | Seba.F1 | API de Windows | 5 | 02-02-2006 00:16:30 |
Application.Terminate | Esau | Varios | 7 | 06-05-2005 14:12:36 |
Application.Terminate Vs Close | neon | Varios | 2 | 30-07-2004 00:11:55 |
|