Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Dudas con Hilo en ejecución

Hola, espero que podais echarme una mano con esto, a ver tengo un boton que hace una llamada a una función, esta realiza una tarea pesada que incluso llega a congelar la aplicación, por ese motivo he empezado a mirarme los hilos y ver un poco como funcionan, me he bajado el pdf de "delphi al limite" ademas de mirar por la web, pero no me aclaro. El problema es que la llamada a la función es la siguiente:

Código Delphi [-]
Procedure TPrincipal.Button1Click(Sender: TObject);
begin
  CortarArchivo(labEdit1.Text,2048);
end;

Y el error que me da al usar el hilo es este...


Como veis, la llamada a la función tiene dos parametros, entonces, suponiendo que fuera button1.Click el encargado de ejecutar el hilo y este a su vez hace la llamada a la función ¿como seria? o dicho de otro modo ¿como le paso al hilo esa función para que ejecute todo el código?

No sé si me he explicado bien, espero que si. Saludos y ojalá podais ayudarme.

Última edición por danielmj fecha: 20-10-2013 a las 22:52:06. Razón: mejorar pregunta
Responder Con Cita
  #2  
Antiguo 20-10-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Ufff, creo que es más fácil un simple copia y pega del mensaje, ¿no crees?
Cita:
[dcc32 Error] ZIZ.pas(784): E2010 Incompatible types: 'TThreadMethold' and 'procedure', untyped pointer or untyped parameter'
Responder Con Cita
  #3  
Antiguo 20-10-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 danielmj.

Publicá la declaración de la tu clase TThread y del procedimiento "CortarArchivo". Por el texto del mensaje de error y por como realizas la llamada, parece que lo has declarado como un procedimiento normal y no como método de una clase TThread.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo 20-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Ufff, creo que es más fácil un simple copia y pega del mensaje, ¿no crees?
jaja es cierto, me complique mas de la cuenta. Saludos.
Responder Con Cita
  #5  
Antiguo 21-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Hola ecfisa, saludos

mira..

Declaración del hilo...
Código Delphi [-]
...
private
{ Private declarations }
Thread: TStopStartThread;
WaitThread: TWaitThread;
UntilFlag: TEvent;
...

hago la llamada al hilo...
Código Delphi [-]
Procedure TPrincipal.Button1Click(Sender: TObject);
begin
  Thread.MsgWaitFor(CortarArchivo(labEdit1.Text,2048), nil); //---> Aquí me da el error o uno de los que posiblemente me vaya a dar.
  //CortarArchivo(labEdit1.Text,2048); --> esta linea esta operativa en este momento ya que el hilo  lo tengo "anulado" por no correr.
end;

Procedimiento "CortarArchivo"...
Código Delphi [-]
procedure CortarArchivo(sArchivo: TFileName; iLongitudTrozo: Long64 );
var
  i: Word;
  FS, Stream: TFileStream;
  nombreFile: String;

  label iniciar;

begin
  try
    principal.memo1.Lines.Add(CalcHash(principal.labedit1.Text,haSHA1));
    principal.Memo1.Lines.SaveToFile(principal.labEdit2.Text+ '\'+ extractFileName(principal.LabEdit1.Text+'.crc'));
  except
    on EFCreateError do
      begin
        showMessage ('Unidad seleccionada no válida. Selecciona una unidad' +
        chr(13)+'de disco duro local que sea accesible.');
        principal.Memo1.Text:= '';
        exit;
      end;
  end;

    if principal.opc1.Checked then
    begin
      iLongitudTrozo:= 1048576;        //1MB  --> los tamaños se muestran en Mbytes
      //sArchivo:= principal.LabEdit2.Text;

      FS := TFileStream.Create(sArchivo, fmOpenRead or fmShareDenyWrite);
    try
      principal.Memo2.Lines.Add((Chr(13))+(Chr(10)));
      principal.Memo2.Lines.Add('LISTADO DE ARCHIVOS [ORIGINAL CORTADO]');
      principal.Memo2.Lines.Add((Chr(13))+(Chr(10))+'·································');

      for i := 1 to Trunc( FS.Size / iLongitudTrozo ) + 1 do
      begin
        principal.prBar.Max:= FS.Size div iLongitudTrozo;
        principal.prBar.Position:= i;
        principal.prBar.Refresh;

        nombreFile:= extractFileName(sArchivo);
        try
          sArchivoPartido := ChangeFileExt(principal.labEdit2.Text +'\'+
          nombreFile, '.' + FormatFloat('000', i ) );
          Stream := TFileStream.Create(sArchivoPartido, fmCreate or fmShareExclusive);
        except
        on EFileStreamError do
        ShowMessage ('Unidad seleccionada no valida. Selecciona una unidad de disco duro local.');

        end;
          principal.labEdit2.SelStart:= 0;
          principal.labEdit2.SelLength:= length(principal.labEdit2.Text);
        if (principal.labEdit2.SelLength) = 3 then
            principal.Memo2.Lines.Append(principal.labEdit2.Text + extractFileName(sArchivoPartido))
        else
          principal.Memo2.Lines.Append(principal.labEdit2.Text+'\'+extractFileName(sArchivoPartido));

      try
        if fs.Size - fs.Position < iLongitudTrozo then
          iLongitudTrozo := FS.Size - FS.Position;
          Stream.CopyFrom( FS, iLongitudTrozo );
      finally
        Stream.Free;
      end;
  end;
  finally
  FS.Free;
  principal.Button1.Enabled:= false;

  principal.Memo2.Lines.Add((Chr(13))+ (chr(10)));
  principal.Memo2.Lines.Add('Archivo original: '+principal.LabEdit1.Text);
  principal.memo2.Lines.Add('Ruta destino: '+principal.labEdit2.Text);
  principal.Memo2.Lines.Add('Código HASH: '+principal.Memo1.Text);

  end;
    if principal.prBar.Max = principal.prBar.Position then
    principal.Timer1.Enabled:= true;
    Principal.lblTerminado.Visible:= true;
end;
...
    if principal.opc1.Checked then
    begin
      iLongitudTrozo:= 16106127360;        //15GB
      FS := TFileStream.Create( sArchivo, fmOpenRead or fmShareDenyWrite);
    try
      Principal.Label6.Caption:= IntToStr((FS.Size div iLongitudTrozo) +1);
      principal.Label6.Refresh;

      principal.Memo2.Lines.Add((Chr(13))+(Chr(10)));
      principal.Memo2.Lines.Add('LISTADO DE ARCHIVOS [ORIGINAL CORTADO');
      principal.Memo2.Lines.Add((Chr(13))+(Chr(10))+'·································');

      for i := 1 to Trunc( FS.Size / iLongitudTrozo ) + 1 do
      begin

        principal.prBar.Max:= Round((FS.Size / iLongitudTrozo));
        principal.prBar.Position:= i;
        principal.prBar.Refresh;

        sArchivoPartido := ChangeFileExt(principal.labEdit2.Text +'\'+
        nombreFile, '.' + FormatFloat('000', i ) );
        Stream := TFileStream.Create(sArchivoPartido, fmCreate or fmShareExclusive);

        principal.labEdit2.SelStart:= 0;
        principal.labEdit2.SelLength:= length(principal.labEdit2.Text);
        if (principal.labEdit2.SelLength) = 3 then
            principal.Memo2.Lines.Append(principal.labEdit2.Text + extractFileName(sArchivoPartido))
        else
          principal.Memo2.Lines.Append(principal.labEdit2.Text+'\'+extractFileName(sArchivoPartido));
      try
        if fs.Size - fs.Position < iLongitudTrozo then
          iLongitudTrozo := FS.Size - FS.Position;
          Stream.CopyFrom( FS, iLongitudTrozo);
      finally
        Stream.Free;
      end;
  end;
  finally
  FS.Free;
  principal.Button1.Enabled:= false;

  principal.Memo2.Lines.Add((Chr(13))+ (chr(10)));
  principal.Memo2.Lines.Add('Archivo original: '+principal.LabEdit1.Text);
  principal.memo2.Lines.Add('Ruta destino: '+principal.labEdit2.Text);
  principal.Memo2.Lines.Add('Código HASH: '+principal.Memo1.Text);
  end;
    if principal.prBar.Max = principal.prBar.Position then
    principal.Timer1.Enabled:= true;
    Principal.lblTerminado.Visible:= true;
  end;
end;

Así está ahora mismo, ¿alguna sugerencia?
Una cosa, no seais muy duros con el código que estoy verdecillo ya sé que habra mil formas de hacerlo mas claro y limpio pero todo a su tiempo. De momento funciona que no es poco jajaj.

P.D.: El ejemplo que uso de hilo es de la web "crea tu software" y no sé si será valido en mi caso.

Saludos y gracias.

Última edición por danielmj fecha: 21-10-2013 a las 00:25:31. Razón: error al copiar
Responder Con Cita
  #6  
Antiguo 21-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Buenas,

Ya lo tengo solucionado, el error era mi despiste y no estudiar bien las explicaciones, a ver el problema estaba (o eso entiendo) que para pasar parametros a un hilo, hay que declarar un type tal que este:

Código Delphi [-]
type
  TData = record
  Codigo: integer;
  Nombre: string;
end;

Obviamente, cambiando nombres, y esto yo no lo hacía. Por otra parte, tampoco declaraba en el uses la unidad "ActiveX", y esta es necesaria para incializar el hilo con el parametro "CoInitialize"

Código Delphi [-]
procedure TJoin.ThreadExample(Data: pointer);
begin
  CoInitialize(nil);
  UnirArchivo(labEdit1.Text,labEdit2.Text);
end;

Bueno, esa es la solución. Espero que le sirva a alguien.
Saludos.

Última edición por danielmj fecha: 21-10-2013 a las 12:58:42. Razón: error al escribir
Responder Con Cita
  #7  
Antiguo 21-10-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 danielmj.

Gracias por presentarnos la solución

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #8  
Antiguo 21-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
bueno, bien o mal explicado, creo que puede ayudar a alguien o eso espero. En cuanto al hilo, ya está corriendo

saludos.
Responder Con Cita
  #9  
Antiguo 23-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Hola nuevamente,
Parece que no es oro todo lo que reluce... y digo esto por que si bien el hilo ya corre, cuando pulso el botón para salir (o matar al hilo), no hace ni caso y el proceso sigue...

Este es código que tengo puesto para cortar el hilo definitivamente y salir de la aplicacion:
Código Delphi [-]
if Assigned(WaitThread) then WaitThread.AbortThread;
    if Thread.Waiting then Thread.AbortThread;
    begin  
      thread.Terminate;
      WaitThread.Terminate;
      FreeAndNil(thread);
      Thread.Free;
      UntilFlag.Free;
   end;
close

¿que hago mal?

Saludos y gracias.

Última edición por danielmj fecha: 23-10-2013 a las 00:27:16. Razón: error al escribir código
Responder Con Cita
  #10  
Antiguo 23-10-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
No sé que otras cosas harás mal, pero esto sí que está mal:
Código Delphi [-]
FreeAndNil(thread);
thread.Free;

Con FreeAndNil liberas la memoria ocupada y la pones a nulo. Luego con Free ... ya no hay nada que liberar, en teoría.
Responder Con Cita
  #11  
Antiguo 23-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Gracias por el apunte casimiro, soy de los que piensa que hay que ser humilde en todos los aspectos de la vida de ahí que sepa reconocer mis errores. Es por eso que os pido consejo sobre tal o cual código, afortunadamente son pocas las otras cosas que hago mal, y aunque la programacion no me vaya a dar de comer (es mas una aficion) el trabajar de 7 de la mañana a 8 de la tarde en un torno paralelo o en la centina de un remolcador, si se me da bien desde hace ya 25 años.
una vez mas gracias por tu comentario lo estudiare y lo pondre en practica a ver que tal.
Responder Con Cita
  #12  
Antiguo 23-10-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Y trabajas de tornero en la sentina de un remolcador?
Responder Con Cita
  #13  
Antiguo 23-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
si te fijas en mi anterior texto use "o" para referirme a una cosa u otra, es decir dicho de modo facilmente entendible, a veces el trabajo exige que este 12 horas de pie en el torno y otras que este doblado como un 8 entre tuberias de gasoil, aceite hidraulico etc en la sentina de un barco o en la sala de maquinas de este. Y no sabes como de reventado se llega a casa... pero es lo que hay. La programacion en mi caso es mas una especie de terapia de desconexion del dia a dia y si encima aprendo pues mejor. Saludos.
Responder Con Cita
  #14  
Antiguo 23-10-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sí, es un trabajo duro.
Responder Con Cita
  #15  
Antiguo 23-10-2013
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
danielmj,

Cita:
Empezado por danielmj
...La programación en mi caso es mas una especie de terapia de desconexión del día a día y si encima aprendo pues mejor...


Nelson.
Responder Con Cita
  #16  
Antiguo 23-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
Saludos y vuelta con lo mismo...

He modificado el código como me sugería casimiro (lo que ahora no sé es si le entendí bien), el caso es es que el código queda así...
Código Delphi [-]
try
    if Assigned(WaitThread) then WaitThread.AbortThread;
      if Thread.Waiting then Thread.AbortThread;
        thread.Terminate;
        close
  except
    thread.Free;
  raise
  end;

Añado que esta modificación la hago en base a una discusión en stackoverflow que encontré no hace ni media hora. Dicho esto, cuando pulso sobre "cerrar" el formulario se cierra pero en segundo plano el hilo sigue corriendo, si pulso la "X" de cerrar me tira este error (ver captura). Si vuelvo a pulsar la "X" parar cerrar el formulario "a las bravas" se repite el mismo mensaje de error y ya luego si se cierra todo y sale del programa.

Mensaje de error 1:


Mensaje de error2 (lo muestra si pulso "continue" en el primer error):


Entonces, ¿de que forma se detiene correctamente un hilo que se esta ejecutando en el momento de detenerse?

P.D.: Saludos nelson, me alegra que estes de acuerdo con mi afirmación aunque veces la terapia me crispa los nervios jaja.

Última edición por danielmj fecha: 23-10-2013 a las 21:33:21. Razón: faltaba informacion
Responder Con Cita
  #17  
Antiguo 23-10-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por danielmj Ver Mensaje
He modificado el código como me sugería casimiro (lo que ahora no sé es si le entendí bien), el caso es es que el código queda así...
je, je... aunque yo solamente comenté que sobraba el thread.free, porque ya lo habías liberado en la línea anterior con freeAndNil(thread)
Responder Con Cita
  #18  
Antiguo 27-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
hola a todos,

sigo con lo mismo, parece que se corta el hilo pero sigue con el proceso en segundo plano. ahora el código solo tiene

Código Delphi [-]
thread.terminate;
thread.freeOnterminate:= true;

Pero como digo, sigue con el proceso de unir el archivo en segundo plano, y cuando pulso la "x" para salir del formulario, me tira dos mensajes de error como las capturas de mas arriba.

¿alguna idea?
Gracias.
Responder Con Cita
  #19  
Antiguo 27-10-2013
Avatar de danielmj
danielmj danielmj is offline
Miembro
 
Registrado: jun 2011
Posts: 383
Poder: 13
danielmj Va por buen camino
error al salir

Hola, ¿por que si en el boton de salir unicamente tengo "Close" me da dos errores en forma de excepcion? lo esquematizo un poco para situaros...

Código Delphi [-]
FORMULARIO PRINCIPAL
           BOTON1 --> LLAMA AL FORMULARIO CORTAR
           BOTON2 --> LLAMA AL FORMULARIO UNIR 
           BOTON3 --> SALIR
               CODIGO BOTON3 --> "close"

No entiendo por que me da error cuando solo tiene la orden de salir y cerrar la aplicacion, a no ser que haya heredado algun "estado" de los formularios cortar/unir y lo tenga en memoria a la hora de salir de la aplicacion. Pero si es por ese motivo, tampoco sé como liberarlo.
¿alguna idea? gracias y un saludo.
Responder Con Cita
  #20  
Antiguo 27-10-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
No somos adivinos ni tenemos una bola mágica. Creo que ya has leido nuestra guía de estilo, pues eso
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
Pasar cadena de conexion a tadoconnections dentro de un hilo de ejecucion richy08 OOP 4 03-08-2010 00:49:32
como crear un hilo de ejecucion ayudenme plis!!! jazmin OOP 4 21-06-2010 10:55:13
cuando llamo ejecutar un hilo dentro del proceso del hilo no lo hace robertosc Varios 1 14-08-2007 23:11:09
Dudas Crear Objetos en Tiempo de Ejecución Deiv OOP 9 09-08-2007 02:13:15
Parar un hilo de ejecución deivi Varios 6 21-11-2006 14:36:49


La franja horaria es GMT +2. Ahora son las 13:46:02.


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