Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Iniciar un TThread en un Form crear en runtime (https://www.clubdelphi.com/foros/showthread.php?t=83318)

joseprad 03-06-2013 15:59:52

Iniciar un TThread en un Form crear en runtime
 
Hola amigos:

Tengo un problema que no consigo resolver, ni encontró información en Internet.

Tengo un programa principal, que ha modo de menú general, abre diferentes formularios con el procedimiento:
Código Delphi [-]
with TForm1.Create(self) do begin
showModal;
free;
end;

Esto, me funciona perfectamente hasta que en un formulario abierto en tiempo de ejecución, intento crear un nuevo hilo.

El programa es una prueba de programa multi hilo, que me baje de Internet.
Código Delphi [-]
procedure TReloj.ActualizaTexto;
begin
  Form8.lbl1.Caption:=IntToStr(Hora);
end;

procedure TReloj.Execute;
begin
  Salir := False;
  Hora := 0;
  while not Salir do begin
    Synchronize(ActualizaTexto);
    sleep(1000);
    inc(Hora);
  end;
end;

Cuando lo ejecuto se ejecuta synchronize y pasa a ejecutar ActualizarTexto me da el siguiente error:
'Access violation at address 00A16CD2 in module 'MenuAplicacion'.Read of address '00000390'.

En cambio si lo ejecuto como programa principal, funciona perfectamente y no da ningún error.

Agradeceré cualquier ayuda

Neftali [Germán.Estévez] 03-06-2013 17:40:57

No parece que en ese código exista ningún problema, pero habría que ver el código completo de la llamada y del Thread.
La mayoría de los problemas con hilos llegan por intentar acceder a elementos que no están definidos en el thread (sin sincronizar).

Con esto que pones es difícil....

joseprad 09-06-2013 09:50:50

Lo curioso es que si arranco directamente el programa que ejecuta el TThread, funciona correctamente.
El error lo da si genero el formulario en runTime

nlsgarcia 10-06-2013 04:32:41

joseprad,

Cita:

Empezado por joseprad:

...El programa es una prueba de programa multi hilo...

...Cuando lo ejecuto se ejecuta synchronize y pasa a ejecutar ActualizarTexto me da el siguiente error: 'Access violation at address 00A16CD2 in module 'MenuAplicacion'.Read of address '00000390'...

...si lo ejecuto como programa principal, funciona perfectamente...

...si arranco directamente el programa que ejecuta el TThread, funciona correctamente...

Pregunto:

1- ¿El formulario Form8 esta instanciado al momento de la falla?

2- ¿Puedes colocar el código es cuestión para analizar el problema?

Espero sea útil :)

Nelson.

joseprad 16-06-2013 13:59:58

Hola Nelson.

Te adjunto el código completo del Form8

Código Delphi [-]
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, JfLabel, JfButtons, ExtCtrls;

type
  TForm8 = class(TForm)
    btoIniciar: TJfBitBtn;
    btoParar: TJfBitBtn;
    lbl1: TLabel;
    procedure btoIniciarClick(Sender: TObject);
    procedure btoPararClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TReloj = class(TThread)
  private
    Hora: Integer;
    Salir: Boolean;
    procedure ActualizaTexto;
  protected
    procedure Execute; override;
    procedure Terminar;
  end;

var
  Form8: TForm8;
  Reloj: TReloj;
  Corriendo: Boolean;

implementation

{$R *.dfm}
{ TReloj }

procedure TReloj.ActualizaTexto;
begin
  Form8.lbl1.Caption:=IntToStr(Hora);
end;

procedure TReloj.Execute;
begin
  Salir := False;
  Hora := 0;
  while not Salir do begin
    Synchronize(ActualizaTexto);
    sleep(1000);
    inc(Hora);
  end;
end;

procedure TReloj.Terminar;
begin
  Salir := true;
end;

procedure TForm8.btoIniciarClick(Sender: TObject);
begin
  if not Corriendo then begin
    Reloj := TReloj.Create(False);
    Corriendo := true;
  end;

end;

procedure TForm8.btoPararClick(Sender: TObject);
begin
  if Corriendo then begin
    Reloj.Terminar;
    Reloj.Free;
    Corriendo := False;
  end;
end;

procedure TForm8.FormCreate(Sender: TObject);
begin
  Corriendo := False;
end;

end.

Este programa que no es mas que un contador, funciona perfectamente.

Pero si lo arranco desde otro programa con:

Código Delphi [-]
with TForm8.Create(self) do begin
   ShowModal;
   Free;
end;

entonces me da el error.

Saludos

beginner01 16-06-2013 21:51:03

Cita:

Empezado por joseprad (Mensaje 462318)
Hola Nelson.

Te adjunto el código completo del Form8

Código Delphi [-]
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, JfLabel, JfButtons, ExtCtrls;

type
  TForm8 = class(TForm)
    btoIniciar: TJfBitBtn;
    btoParar: TJfBitBtn;
    lbl1: TLabel;
    procedure btoIniciarClick(Sender: TObject);
    procedure btoPararClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TReloj = class(TThread)
  private
    Hora: Integer;
    Salir: Boolean;
    procedure ActualizaTexto;
  protected
    procedure Execute; override;
    procedure Terminar;
  end;

var
  Form8: TForm8;
  Reloj: TReloj;
  Corriendo: Boolean;

implementation

{$R *.dfm}
{ TReloj }

procedure TReloj.ActualizaTexto;
begin
  Form8.lbl1.Caption:=IntToStr(Hora);
end;

procedure TReloj.Execute;
begin
  Salir := False;
  Hora := 0;
  while not Salir do begin
    Synchronize(ActualizaTexto);
    sleep(1000);
    inc(Hora);
  end;
end;

procedure TReloj.Terminar;
begin
  Salir := true;
end;

procedure TForm8.btoIniciarClick(Sender: TObject);
begin
  if not Corriendo then begin
    Reloj := TReloj.Create(False);
    Corriendo := true;
  end;

end;

procedure TForm8.btoPararClick(Sender: TObject);
begin
  if Corriendo then begin
    Reloj.Terminar;
    Reloj.Free;
    Corriendo := False;
  end;
end;

procedure TForm8.FormCreate(Sender: TObject);
begin
  Corriendo := False;
end;

end.

Este programa que no es mas que un contador, funciona perfectamente.

Pero si lo arranco desde otro programa con:

Código Delphi [-]
with TForm8.Create(self) do begin
   ShowModal;
   Free;
end;

entonces me da el error.

Saludos


Hola.

Si te fijas en el código en rojo estas utilizando la variable Form8 que hace referencia a la clase TForm8, a la cual no le estas asignando ningún valor por lo que tiene un valor nil o nulo y si intentas hacer referencia a esta (invocar métodos o acceder a sus propiedades) Delphi te devolverá un error "Acces Violation". Una solución para tu caso es asignarle la referencia del formulario creado para que puedas acceder a él.
Código Delphi [-]
  {
  Creamos el formulario y le asignamios la referencia a la variable Form8.
  }
  Form8 := TForm8.Create(self);
  with Form8 do
  try
     ShowModal;
  finally
     Free;
  end;


try..finally

joseprad 22-06-2013 18:29:24

Muchas gracias amigo.
Como dicen en mi tierra siempre ven mas cuatro ojos que dos.


La franja horaria es GMT +2. Ahora son las 02:58:36.

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