Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Problema: Hilo No ejecuta Procedimiento de su formulario. (https://www.clubdelphi.com/foros/showthread.php?t=79472)

aoshishin1 09-07-2012 18:37:27

Problema: Hilo No ejecuta Procedimiento de su formulario.
 
Buenos dias, es la primera ves que posteo aqui ya que hace poco eh empezado a usar delphi y la verdad esta comunicadad me ha salvado mucho al vida.

Bueno, resulta que me he topado con el siguiente problema.

Tengo un proyecto en delphi el cual tengo un formulario de tipo MDIForm, el cual abro una ventana llamada FrmAuxialiar de tipo medichild (hija del otro formulario).

Dentro de esta ventana hija tengo creado un hilo, lo que quiero hacer es ejecutar dentro de este hilo un procedimiento declarado dentro de mi FrmAuxiliar, el problema es que cuando hago el excute, no me toma ese procedimiento, no lo reconoce, es como si el hilo no supiera donde se encuentra declarado o parado por asi decirlo.

Me gustaria saber uan forma de poder llamar a estos procedimientos dentro de mi hilo, para asi poder hacer esta multitarea,les muestro el codigo.

Código Delphi [-]
unit UTFrmAuxialiar;

interface

uses


  type
  THilo = class(TThread)
    Lista: TListBox;
    procedure Execute; override;
    procedure MostrarContador;
    procedure Terminar;
  end;

  private
    Hilo : Thilo;



//------------------------------------------------------------------------------
procedure THilo.Execute;
var
  i : integer;
begin
  inherited;
  FreeOnTerminate := True;
  while not terminated do
  begin
   FrmAuxialiar.MostrarCargando;
  end;
end;

procedure THilo.MostrarContador;
begin
  FrmAuxialiar.MostrarCargando;
end;

procedure THilo.Terminar;
begin
  FrmAuxialiar.OcultarCargando;
  Terminate;
end;
//---------------------------------------------------------
procedure TFrmAuxialiar.MostrarCargando;
begin
   Panel20.Visible:=true;
   AdvCircularProgress1.Enabled := true;
end;

procedure TFrmAuxialiar.Nuevo1Click(Sender: TObject);
begin
 hilo:=Thilo.Create(False);
 hilo.Resume;
end;
Como veran, cuando hagvo el execute, me deberia de mostrar un panel y un circularbar, pero no lo hace.
Desde ya muchas gracias y espero que me brinde una pequeña ayuda.
Saludos!!

escafandra 09-07-2012 20:14:51

Estudia el metodo Synchronize en la ayuda de delphi.

Saludos.

aoshishin1 09-07-2012 23:43:28

Muchas gracias por tu respuesta, ya supe cual fue el error, ahorra miduda es al siguiente, me gustaria saber que tanta versatibilidad tiene un hilo para correr en segundo plano un procedimiento que no es propio de el, pro ejemplo.

Código Delphi [-]

procedure THilo.Execute; 
var   i : integer; 
begin   
inherited;   
FreeOnTerminate := True;   
while not terminated do   
begin   
Synchronize(MostrarContador);   
end; 
end;

 procedure THilo.MostrarContador; 
begin   
FrmAuxialiar.MostrarCargando; 
end;

procedure TFrmAuxialiar.MostrarCargando;
var
  i:integer;
begin
 i:=1;
 While i>0 do
  begin
 i:=i+1; 
 end;
end;

Estoy forzando a un bucle infinito, y quiero ver si se respeta la concurrencia, pero al hacer esto se me traba la pantalla.
Me gustaria saber el por que, y si hay alguna manera que el procedimiento "Mostrarcargando" se pueda correr paralelamente sin definirlo dentro del hilo.

Muchas gracias!!!!!

escafandra 10-07-2012 08:09:23

No olvides poner las etiquetas de código para que éste sea legible.

Lo que bloquea tu APP es FrmAuxialiar pues éste bloquea los mensajes de la App.

Mira esto:

Código Delphi [-]
procedure THilo.Execute;
begin
  FreeOnTerminate := True;
  while not terminated do
    Synchronize(FrmAuxialiar.MostrarCargando);
end;

procedure TFrmAuxialiar.MostrarCargando;
var
  i:integer;
begin
  i:=1;
  Show;
  While i>0 do
  begin
    Application.ProcessMessages;
    i:=i+1;
  end;
end;

Este ejemplo es un tanto absurdo pues el bucle del thread llama repetidamente a un método de un formulario que presenta un bucle infinito con lo que el bucle del Thread se ejecuta sólo una vez...

El método Execute del thread no tiene porqué tener un bucle, en ese caso termina cuando termine Exectue. Tu decides lo que tiene que hacer.


Saludos.

aoshishin1 10-07-2012 16:21:14

Buenos dias, Escafranda mcuhas gracias por aclararmelas varias dudas con tu comentario, ahora me gustaria saber las dos cosas siguientes si eres tan amable:

1- Un hilo termina cuando termina de ejectar el execute?, o cuando ejecuto el terminate?

2- El objetivo mio era que el codigo del Frmuxiliar.mostrarcargando se corriera en segundo plano de manera que no haga trabar la ventana, perocomo este es propio del formulario no se si habra alguna forma de hacer eso, de llamar ese procedimiento y se ejecute en segundo plano sin que me haga trabar la pantalla.

Espero su pronta respuesta y muchas gracias!!

escafandra 10-07-2012 18:47:49

Un hilo termina cuando termina su bucle principal. Si miras el ejempo que te puse, ya no se traba al añadir Application.ProcessMessages;

Si no quieres que aparezca ningún formulario, creo que es mas lógico que no uses uno sino que tu función pertenezca al thread.

Saludos.

escafandra 10-07-2012 20:01:25

Cita:

Empezado por aoshishin1 (Mensaje 437050)
2- El objetivo mio era que el codigo del Frmuxiliar.mostrarcargando se corriera en segundo plano de manera que no haga trabar la ventana, perocomo este es propio del formulario no se si habra alguna forma de hacer eso, de llamar ese procedimiento y se ejecute en segundo plano sin que me haga trabar la pantalla.

Si lo que quieres es no acceder a ningún elemento visual del FrmAuxialiar, ningún componente de la VCL existente en él desde el Thread, entonces no te hace falta usar Synchronize. Lee en la ayuda de delphi su razón de ser. En ese caso, y al no usar Synchronize, tampoco será necesario el uso de ProcessMessages y el código funciona bien así:

Código Delphi [-]
procedure THilo.Execute;
begin
  FreeOnTerminate := True;
  while not terminated do
    FrmAuxialiar.MostrarCargando;
end;

procedure TFrmAuxialiar.MostrarCargando;
var
  i:integer;
begin
  i:=1;
  While i>0 do
    i:=i+1;
end;
Ahora lo que tienes que ver es que es lo que quieres que tu código haga.


Saludos.

Chris 10-07-2012 21:37:57

Una pregunta: ¿Pará qué utilizas un segundo hilo sólo para mostrar un panel? Mostrar un panel toma un par de milisegundos. Un tiempo invisible al usuario. Si mostrar el panel es el único propósito del hilo, te estás complicando la vida.

Si hicieras cálculos complicados que toman más de un segundo en procesarse, un hilo independiente sería una buena idea. Pero en este caso no le encuentro el sentido.

Aparte, a cómo lo estás haciendo ahora, estás introduciendo bugs en tu aplicación. En tu código veo líneas propicias a EAccessViolation.

escafandra 11-07-2012 00:10:47

Yo creo que hasta ahora son meras pruebas de funcionamiento. El propósito final no está claro...

Saludos.

Al González 11-07-2012 02:27:22

Hola, sólo añadir para aoshishin1 (¡salud!), que la funcionalidad de Synchronize es semejante a la del evento OnIdle de la aplicación (o de un objeto TApplicationEvents), es decir, el código de interés es ejecutado por el hilo principal de la aplicación (como si el hilo alterno no existiese).

Synchronize tiene mayor utilidad cuando el método Execute del nuevo hilo realiza otras tareas en verdadero segundo plano. Así, las tareas que pueden no ser seguras para hilos (thread-safe) se delegan al hilo principal a través de método Synchronize. Básicamente, las tareas no seguras para hilos son aquellas que afectan a regiones de memoria que varios hilos comparten, como puede ser cambiar o destruir un objeto al que instantes después otro hilo (como el principal) intentaría acceder.

Por otra parte, aunque sea algo sobrado para lo que busca aoshishin1, cabe mencionar que como alternativa a Synchronize está el uso de secciones críticas.

Saludos cordiales. :)


La franja horaria es GMT +2. Ahora son las 11:33:08.

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