Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Lazarus, FreePascal, Kylix, etc.
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-12-2013
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
manejo de threads ...

hola amigos,

La verdad no he usado threads porque, en teoria, no me han hecho falta .
tengo una aplicacion que se conecta remotamente a una base de datos firebird y quería poder poner un progressbar mientras se espera que se carguen algunos datos.
Ya estuve mirando sobre los threads con algunos enlaces que habeis recomendado pero no me aclaro mucho.
Mi idea es que saque el progressbar en pantalla mientras se carguen los datos o una animacion, el caso es que no parezca que se ha congelado la aplicacion mientras esta en el proceso.

Estaba probando este ejemplo pero no va muy bien:
Código Delphi [-]
type
{ TMiHilo }

  TMiHilo = class(TThread)
  private
    procedure AvanzaBarra;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: boolean);
  end;


  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    ProgressBar1: TProgressBar;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
    MiHilo : TMiHilo;
    begin
        //creamos el hilo, pero no lo iniciamos
        MiHilo := TMiHilo.Create(True); // Con el parametro true no se inicia automaticamente
        if Assigned(MiHilo.FatalException) then
           raise MiHilo.FatalException;
        //si no hay ninguna excepción lo iniciamos
        MiHilo.Start;

end;
{ TMiHilo }

procedure TMiHilo.AvanzaBarra;
//Este metodo solo es llamado por Synchronize(@AvanzaBarra) y por ello
// es ejecutado por el hilo principal.
//El hilo principal puede acceder a los elementos visuales del GUI por ejemplo a la progressbar
begin

    Form1.ProgressBar1.StepIt;

    if Form1.ProgressBar1.Position = Form1.ProgressBar1.Max then begin
        Form1.ProgressBar1.Position := 0;
    end;
end;

//Este proceso se ejecuta al iniciar el hilo
procedure TMiHilo.Execute;
begin

    //mientras no termine y sea verdadero se ejecutará
    while (not Terminated) and (true) do begin
        //este loop es del hilo principal
        Synchronize(@AvanzaBarra);
    end;
end;

constructor TMiHilo.Create(CreateSuspended: boolean);
begin
    //Con esta propieda del hilo no necesitamos liberarlo manualmente al terminar de ejecutar el hilo
    FreeOnTerminate := True;
    inherited Create(CreateSuspended);
end;


end.

Le doy al botón para que inicie pero no se llena la barra.
Ademas no veo donde puedo colocar el codigo para que mi aplicacion continue.

Si me orientais un poco .
Responder Con Cita
  #2  
Antiguo 08-12-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola anubis.

En este enlace: Velocidad de un timer, tenes un ejemplo de como implementar un timer con thread. Escribí el código para Delphi pero lo acabo de probar en Lazarus y funciona perfectamente con solo hacer unos pequeños cambios.

En la unidad uTimeThread:
Código Delphi [-]
procedure TTimeThread.Execute;
begin
  while not Terminated do
    Synchronize(@WaitInterval);  // <--- "@" agregado
end;

Y en el ejemplo de uso:
Código Delphi [-]
procedure TForm1.btnComenzarClick(Sender: TObject);
begin
  if not Assigned(TimeThread) then
  begin
    FCont := 1;
    TimeThread:= TTimeThread.Create;
    // Intervalo expresado: 1/1000000 seg. (µs)
    TimeThread.Interval := 100000; {1/10 seg }
    TimeThread.OnTime   := @TimeThreadOnTime; // <--- "@" agregado
    TimeThread.Execute;
  end;
end;
La adaptación a un TProgressBar es tan simple como:
Código Delphi [-]
procedure TForm1.TimeThreadOnTime;
begin
  if (ProgressBar1.Position = 100) and Assigned(TimeThread) then
    TimeThread.Terminate;
  ProgressBar1.Position:= FCont;
  Inc(FCont);
  Application.ProcessMessages;
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 08-12-2013
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Gracias, ya lo implemente, pero me surgen algunas dudas.

En teoria siempre hay que usar un timer para el thread?.

Tengo que ver mas a fondo los threads porque no me aclaro mucho la verdad.

Si pongo el inicio del thread en el form1.activate, hago lo que tiene que hacer los procesos, cuando acaban de inicio, ya le pongo la procedure finalizar. Aun asi, con todo y todo, se tarda algo.

En el create no se puede porque todavia no esta creado el form.

Si es un poco de lio los threads. Sabeis algun enlace donde pueda ver bien los threads?. Ya vi los del wiki, pero me lian.

gracias
Responder Con Cita
  #4  
Antiguo 08-12-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola anubis
Cita:
En teoria siempre hay que usar un timer para el thread?.
No, los hilos se pueden utilizar para realizar cualquier proceso.

Cita:
En el create no se puede porque todavia no esta creado el form.
Podes hacer:
Código Delphi [-]
...
uses ..., Windows, Messages;

const
  WM_AFTER_CREATE = WM_USER + 300;
type
  TForm1 = class(TForm)
  ...
  private
    ...
    procedure WmAfterCreate(var Msg: TMessage); message WM_AFTER_CREATE;
  end;
...
implementation

procedure TForm1.WmAfterCreate(var Msg: TMessage);
begin
  if not Assigned(TuThread) then
  begin  
     TuThread := TTread.Create;
     ...
     TuThread.Execute;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  PostMessage(Handle, WM_AFTER_CREATE ,0, 0);
end;
...

Cita:
Sabeis algun enlace donde pueda ver bien los threads?. Ya vi los del wiki, pero me lian.
Busca artículos, documentos, tutorials, etc en referencia a Delphi, existe mas información que para Lazarus y como ya has visto, la implementación no es tan diferente.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 08-12-2013
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Gracias eficsa, mi intención era:-) muy simple. Como conecto con una base de datos remota y tarda algo, quería visualizar algo que dijera que esta en proceso para que no piensen que esta congelado
Responder Con Cita
  #6  
Antiguo 09-12-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por anubis Ver Mensaje
Gracias eficsa, mi intención era:-) muy simple. Como conecto con una base de datos remota y tarda algo, quería visualizar algo que dijera que esta en proceso para que no piensen que esta congelado
Hola anubis.

¿ Con que RDBMS y componentes estas trabajando ?, para lo que buscas hacer seguramente exista una opción mas simple.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 09-12-2013
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Superserver Firebird en Linux, lazarus y componentes zeos en windows
Responder Con Cita
  #8  
Antiguo 09-12-2013
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.272
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
Una duda.
Lo que necesitas es que no se bloquee la aplicación o mostrar una barra para que se vea que está "bloqueada haciendo algo".
__________________
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
  #9  
Antiguo 09-12-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Tenía la misma duda que Neftali, de ahí mi pregunta anterior.

Por que si se trata solamente de avisar al usuario que se está intentando conectar a la base de datos, bastaría con usar un form no modal con (por ejemplo) un Label para el mensaje, algo como:
Código Delphi [-]
  Form2 := TForm2.Create(Self);
  Form2.Label1.Caption := 'Intentando conectar con la base de datos';
  Form2.Show;
  Form2.Refresh;
  // Intentar la conxión
  ...
  try
    ZConnection1.Connected := True; 
    ...
  except
    ShowMessage('No se puede establecer la conexión con la base de datos');
    ...
  end;
  Form2.Free;
  ...
No uso Zeos, así que el código está redactado sobre el mensaje, es a fin de darte una idea.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #10  
Antiguo 10-12-2013
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Gracias a los dos,

Lo de conectar ya lo hice con una splash y un progress bar y parece que si funciona, igual no sea un metodo elegante, pero si hace su funcion.

El problema lo tengo cuando se crea el form.activate, que tarda un poco, eso ya lo solucione con otro progress bar con un thread que saque de una pagina con un timer, que es lo que preguntaba si siempre era necesario porque aun asi tarda un poquito en desaparecer, ya no se si es por el terminate del thread o no se.

Lo poco que entiendo, de momento, de los threads, es que puedes hacer, por ejemplo, dos tareas a la vez o mas si cabe, pero en este caso dos.

La primera, que vaya cargando los datos mientras aparece un aviso para que no se piense que esta bloqueado, ya puede ser con un progress bar o simplemente una imagen o un label.

La segunda parte que no funciona con el thread, porque el progress bar no avanza y da lo mismo ponerlo o no, porque tarda igual que sino lo pongo. Es cuando pongo el comienzo del thread y despues asigno el dataset (que es remoto) y despues termino el thread. Segun pensaba, el thread es tambien para eso, para segun hacer dos cosas a la vez, si pasarse claro esta.
Responder Con Cita
  #11  
Antiguo 10-12-2013
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
No es mas fácil ver que es lo que está ralentizando la conexión? Yo no trabajo con FB, pero sí con MySQL y nunca mis usuarios han tenido que esperar mas tiempo del normal como para ponerles una barrita que les diga que se "está conectando" y mira que mis usuarios tienen conexiones paupérrimas.
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #12  
Antiguo 10-12-2013
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Si, eso ya lo busque pero parece que no va por ahi, o eso creo.

Uso primero conexion ssh puente para conectarme a la base de datos.

Ya hice primero un programa simple en el que coloco un dbgrid que, a lo sumo tendra 50 clientes, y si, tarda, digamos 15 segundos, evidentemente no voy a esperar que se abra como si estuviera en red local o en la misma computadora. Si bien es cierto que no recomendais hacer 'select * from clientes', si necesito hacer eso para que el usuario elija un cliente de la lista.
Responder Con Cita
  #13  
Antiguo 15-03-2014
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Hola, y gracias a todos por vuestras respuestas.

Ya he optimizado mejor las consultas y es un poco más rápido .
Aún así si tengo intención de usar threats que parece que es lo mejor para muchas cosas .

Con un timer ya lo intente pero parece que cuando se solicita la consulta el timer no salta porque la consulta bloquea la aplicacion, lo que nose es si con un threat tendria que rehacer el programa o se puede implementar de alguna forma.

Honestamente, a pesar de los ejemplos, no me aclaro mucho , aunque intento "ver" la composicion desde todos los angulos, se que deben de ser faciles de usar pero no veo el click, tambien se que no es bueno abusar de los threats .

En definitiva, la pregunta, a ver si voy agarrando el chiste, es si implementando un threat tengo que rehacer el programa o bien es facil implementarlo.

gracias
Responder Con Cita
  #14  
Antiguo 16-03-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola anubis.

Como comentas en el mensaje #5, el problema del retardo se produce en la conexión a la base de datos remota. Entonces, la implementación de threads sólo se justificaría si el usuario de tu aplicación puede desarrollar actividades con tu aplicación aún sin haberse establecido la conexión.

De otro modo, threads mediante o no, el usuario va a tener que aguardar el tiempo que la conexión requiera para empezar a operar.

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #15  
Antiguo 16-03-2014
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Gracias ecfisa.
Lo unico que queria era sacar una imagen diciendo que espere pero la consulta bloquea la aplicacion en lo que tarda en responder. Nicon u show form sirve
Responder Con Cita
  #16  
Antiguo 16-03-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por anubis Ver Mensaje
Gracias ecfisa.
Lo unico que queria era sacar una imagen diciendo que espere pero la consulta bloquea la aplicacion en lo que tarda en responder. Nicon u show form sirve
Hola anubis.

Entonces vuelvo a retomar la idea que te sugerí en el mensaje #9. Ahora crea otro form, quitalo de autocreate forms y agregale un Label, StaticText o el componente que te guste para mostrar el mensaje "Intentando conectar con la base de datos". Para el ejemplo llamémoslo frmMsgWait.

En el DataModule:
Código Delphi [-]
...
implementation

uses Windows, Forms,
     UnitMsgWait; // Formulario del mensaje

procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
  frmMsgWait:= TfrmMsgWait.Create(Application);
  frmMsgWait.BorderStyle:= bsNone;
  frmMsgWait.Show;
  Application.ProcessMessages;
  IBDatabase.DatabaseName := 'UN_SERVER:C:\UN_PROGRAMA\UNA_BD.FDB';
  IBDatabase.Params.Clear;
  IBDatabase.LoginPrompt:= False;
  IBDatabase.Params.Add('user_name=sysdba');
  IBDatabase.Params.Add('password=masterkey');
  try
    IBDatabase.Open;
  except
    MessageBox(0, 'No se pudo establecer la conexión con la base de datos',
      '', MB_ICONERROR);
    Application.Terminate;
  end;
  frmMsgWait.Close;
end;
...
El ejemplo esta redactado en Delphi/IBX que son los componentes que uso, pero creo que en líneas generales tiene muy poca diferencia con Lazarus/Zeos.
Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #17  
Antiguo 16-04-2015
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Retomando un poco el tema de los threads, que me vuelve loco y no doy con ello la verdad.
Si ya tengo mi aplicacion hecha y funcionando, si quiero poner un thread, que seria para poner un form o hacer algo, el thread solo sera para esa cosa que yo le diga sin afectar al programa. Es así?.

Yo bastante burro y mas cuando no duermo o sera que estoy viejo .

En base a todo lo que me habeis dicho anteriormente, con los forms parece que funciona algo pero queria aprovechar para meterle un thread y probar.

Asi que resumo si es que estoy bien.

Mi aplicacion funciona, si en alguna tarea tarda mucho, le meto un thread y en ese thread hago otra cosa mientra la aplicacion sigue su funcionamiento normal puesto que lo tenia como unico hilo (por asi decirlo).

Lo pregunto asi a ver si de esta forma me queda un poco mas claro.

gracias y perdonad
Responder Con Cita
  #18  
Antiguo 16-04-2015
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
anubis,

Cita:
Empezado por anubis
...¿El thread solo sera para esa cosa que yo le diga sin afectar al programa. Es así?...


El hilo solo procesara la parte del programa que quieras que se ejecute en un hilo paralelo al hilo principal, liberando al hilo principal para realizar otras tareas si fuera el caso y sin afectar el rendimiento global de la aplicación en términos generales.

Revisa esta información:
Espero sea útil

Nelson.
Responder Con Cita
  #19  
Antiguo 21-04-2015
Avatar de anubis
anubis anubis is offline
Miembro
 
Registrado: mar 2007
Posts: 863
Poder: 18
anubis Va por buen camino
Si la, ando revisando y me lio la verdad. A ver si saco algo positivo.
Si lo que quiero es un thread de una llamada, a, un form
Responder Con Cita
  #20  
Antiguo 21-04-2015
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
El manejo de Threads "manualmente" es de notoria dificultad.

Hay 2 modelos que solucionan este tema (El modelo de "Actor" y los "CSP"), pero buscando rapido veo que en Delphi no hay nada parecido, lo cual es una lastima.

En el pasado he usado tanto:

http://andy.jgknet.de/blog/bugfix-un...unction-calls/

Como

http://otl.17slon.com/

(Probablemente mejor este, ya que soporta versiones nuevas de Delphi)

y son una *gran* mejora vs. el manejo manual.


----

Pensando "Imposible que en pleno 2015 y Delphi no tenga una forma manera de hacer eso" me puse a buscar mas y veo que: Si!

http://community.embarcadero.com/ind...untime-library

En concreto estas se ven prometedoras:

http://docwiki.embarcadero.com/Libra...hreading.TTask

http://docwiki.embarcadero.com/Libra...eading.TFuture
__________________
El malabarista.
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
Manejo de threads ivanloco Varios 6 21-07-2008 06:20:29
uso de threads JULIPO API de Windows 2 25-07-2007 16:09:06
manejo de arbol de contenidos y manejo se sonido y video Buelos Internet 4 09-07-2007 14:52:45
threads multihilo walito API de Windows 5 13-06-2007 19:34:26
Manejo de threads en Delphi dmasson Varios 3 16-04-2004 15:22:58


La franja horaria es GMT +2. Ahora son las 01:00:07.


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