Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-05-2010
Thoronluin Thoronluin is offline
Miembro
 
Registrado: feb 2009
Posts: 39
Poder: 0
Thoronluin Va por buen camino
EAccessViolation usando Hilos

Hola compañeros:

Tengo un pequeño problemilla. Estoy creando un pequeño programa que en una de las partes crea un hilo que debe ser ejecutado para no quedar bloqueado por otro proceso, el problema es que cuando me ejecuta el hilo me da el siguiente error:

Debugger Exception Notification
Project Servicio.exe raised exception class EAccessViolation with message ' Access violation at Address 004E8B49 in module 'Servicio.exe'. Read of addres 00000667'.

Para poder estudiarlo mejor he incluido un botón que me crea el hilo en lugar de ser otros procesos quienes me lo creen y he descubierto que si lo que ejecuto es un "Showmessage" la cosa va bien pero si otro objeto me da el error en esa línea como si no estuviera creado. El código es el siguiente:

Código Delphi [-]
TPruebaMensaje = class(TThread)
   private
   protected
   public
      procedure Execute; override;
      procedure UpdateProgress;
 end;  

TVentana_Principal = class(TForm)
...

...
Procedure TPruebaMensaje.Execute;
begin
   Synchronize(UpdateProgress);
end;

procedure TVentana_Principal.Button4Click(Sender: TObject);
var
   MensajeThread: TPruebaMensaje;
begin
   MensajeThread := TPruebaMensaje.Create(True);
   MensajeThread.FreeOnTerminate:=true;
   MensajeThread.Resume;
end;

Procedure TPruebaMensaje.UpdateProgress;
begin
   showmessage('hola');        // Prueba 1
   // Ventana_Principal.Memo1.Lines.Add('pepe'); // Prueba 2
end;

Es la primera vez que inicio un hilo en el foro así que espero no haberme saltado nada de la guía de estilo, si es así por favor disculpen y comentenme lo que sea.

Muchas gracias por su tiempo y paciencia.
Responder Con Cita
  #2  
Antiguo 10-05-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.285
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Debes tener en cuenta de a qué cosas accedes desde dentro del hilo.
Si accesdes a elementos externos al hilo, debes hacerlo desde el Synchronize.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 10-05-2010
Thoronluin Thoronluin is offline
Miembro
 
Registrado: feb 2009
Posts: 39
Poder: 0
Thoronluin Va por buen camino
Hola Neftali:

Ante todo muchas gracias por tu pronta respuesta. Con ella, más los dos ejemplos que ví en tu web las cosas me han quedado más claras.

Corrígeme si me equivoco. Puedo:

O incluir el Memo en la declaración del Thread:

Código Delphi [-]
TPruebaMensaje = class(TThread)
   private
   protected
   public
      Memo1: Tmemo;
      procedure Execute; override;
      procedure UpdateProgress;
 end;

O usar la función Synchronize para ejecutar la acción:

Código Delphi [-]
Procedure TPruebaMensaje.Execute;
begin
   Synchronize(Ventana_Principal.Memo1.Lines.Add('pepe'));
end;

O definir la función UpdateProgress como perteneciente a Ventana_Principal y ejecutar:

Código Delphi [-]
Procedure TPruebaMensaje.Execute;
begin
   Synchronize(UpdateProgress);
end;

Muchas gracias por tu ayuda, estoy ansioso por probarlo mañana a primera hora .

Saludos

Última edición por Thoronluin fecha: 10-05-2010 a las 23:43:03. Razón: Corrección
Responder Con Cita
  #4  
Antiguo 11-05-2010
Thoronluin Thoronluin is offline
Miembro
 
Registrado: feb 2009
Posts: 39
Poder: 0
Thoronluin Va por buen camino
He probado las tres cosas pero ninguna funcionó. Lo unico que parece que me elimina el error es modicar el código comos sigue:

Código Delphi [-]
procedure TVentana_Principal.Button4Click(Sender: TObject);
var
   MensajeThread: TPruebaMensaje;
begin
   MensajeThread := TPruebaMensaje.Create(False);
   //MensajeThread.FreeOnTerminate:=true;
   //MensajeThread.Resume;
end;

Pero en ese caso cada vez que se ejecute la línea:

Código Delphi [-]
MensajeThread := TPruebaMensaje.Create(False);

Se me crearía una nueva instancia, el problema ahora es, que las antiguas si no las he liberado posiblemente me estén ahí consumiendo recursos ¿Me equivoco?.

En el ejemplo he puesto un botón pero esas líneas de código las va a llamar un execute de un TIdTCPserver, ejecutandose muchas veces durante la vida del programa.

Saludos.
Responder Con Cita
  #5  
Antiguo 11-05-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.285
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Thoronluin Ver Mensaje

O incluir el Memo en la declaración del Thread:... Synchronize(Ventana_Principal.Memo1.Lines.Add('pepe'));

Puedes definir el memo propiedad (pública) del Thread, por ejemplo, o pasarlo como parámetro en el Create (redefiniendolo).
Cuando crees el Thread o después, si lo creas suspendido, asignas el memo del programa principal a tu propiedad del thread. Luego puedes accederlo.
Código Delphi [-]
TPruebaMensaje = class(TThread)
   private
   protected
   public
      MemoMain: Tmemo;
      procedure Execute; override;
      procedure UpdateProgress;
 end;
...

var
   MensajeThread: TPruebaMensaje;
begin
   MensajeThread := TPruebaMensaje.Create(True);
   MensajeThread.MemoMain := memo1;
   MensajeThread.FreeOnTerminate:=true;
...
Luego, desde el thread, no debes acceder al memo del programa principal:

Código Delphi [-]
Synchronize(Ventana_Principal.Memo1.Lines.Add('pepe'));

Si no al memo del Thread.

Código Delphi [-]
Synchronize(MemoMain.Lines.Add('pepe'));
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #6  
Antiguo 11-05-2010
Thoronluin Thoronluin is offline
Miembro
 
Registrado: feb 2009
Posts: 39
Poder: 0
Thoronluin Va por buen camino
Muchísimas gracias por la respuesta y por la velocidad de ésta. Voy a intentarlo así, ya te contaré.

Saludos
Responder Con Cita
  #7  
Antiguo 11-05-2010
Thoronluin Thoronluin is offline
Miembro
 
Registrado: feb 2009
Posts: 39
Poder: 0
Thoronluin Va por buen camino
Lo he probado, funciona genial, muchísimas gracias por todo.

Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
EAccessViolation Alejandrina OOP 3 05-08-2008 16:02:09
EAccessViolation elorza Varios 2 26-12-2007 11:07:32
Error EAccessViolation chele Firebird e Interbase 0 09-11-2004 16:51:21
EAccessViolation Ester Varios 16 10-09-2004 16:33:20
Error EAccessViolation.... JorgeBec Conexión con bases de datos 5 18-02-2004 22:34:11


La franja horaria es GMT +2. Ahora son las 07:49:30.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi