Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Agregarle parametros al metodo Execute de TThread (https://www.clubdelphi.com/foros/showthread.php?t=50147)

eduarcol 09-11-2007 14:26:58

Agregarle parametros al metodo Execute de TThread
 
hola estoy comenzando la programacion por hilos y ando un poco enrredado en esto:

tengo la siguiente declaracion:

Código Delphi [-]
TCompararMd5 = class(TThread)
     protected
        procedure Execute(nIdx: integer); override;
     end;
  end;

el asunto es que al compilar me da el error:

Cita:

Declaration of 'Execute' differs from previous declaration
segun investigue eso se debe a que los metodos deben declararse como su ancestro, ahora me gustaria saber como puedo hacer para que ese metodo me acepte parametros???

Gracias

eduarcol 09-11-2007 14:39:57

investigando un poco encontre este mensaje de Neftali

Override y Virtual

la duda sigue porq sengun entendi si lo coloco virtual pierdo la herencia del ancestro :confused:

Lepe 09-11-2007 14:58:05

Que yo sepa, no puedes.

En la clase TThread, ya está puesto como Virtual y abstract:
- Por Virtual, ya puedes hacer un override del método.
- Por abstract, no puedes dejar su implementación vacía, si lo haces, en ejecución obtendrás una excepción "abstract error".

Dicho esto, puedes sobreescribir (override) el método, pero no puedes cambiar los parámetros, ni si quiera con overload;

Solución a este paradigma, crear un método nuevo:
Código Delphi [-]
TCompararMd5 = class(TThread)
     protected
        procedure ExecuteWithIndex(nIdx: integer);
        procedure Execute; override;
     end;
  end;

Desde ExecuteWithIndex llamas a Execute tu método que sobreescribe el heredado. Dentro de Execute si puedes usar inherited;
Código Delphi [-]
procedure TCompararMd5.ExecuteWithIndex(nIdx: integer);
begin
  // hacer lo que sea con nIdx;
  Execute; // llamas a tu execute, el que has sobreescrito tú.
end;

procedure TCompararMd5.Execute;
begin

  // llamar al Execute heredado
  inherited;
 // o bien, si deseas dejarlo de forma explícita:
 inherited Execute;
end;

Saludos

Lepe 09-11-2007 15:03:27

Cita:

Empezado por eduarcol (Mensaje 244850)
la duda sigue porq sengun entendi si lo coloco virtual pierdo la herencia del ancestro :confused:

No entiendo muy bien.

Si ahora vas a crear otra clase que hereda de TCompararMd5, sugiero que hagas virtual el ExecuteWithIndex, el Execute lo dejas tal cual, es decir:
Código Delphi [-]
TCompararMd5V2 = class(TCompararMd5)    // versión 2 :D :D
protected
   procedure Execute; override;
end;
Cuando ahora llames a Execute, se ejecutarán en este orden:
TCompararMd5V2.Execute que al llamar a inherited ejecutará:
TCompararMd5.Execute que al llamar a inherited ejecutará:
TThread.Execute

Saludos

eduarcol 09-11-2007 15:03:50

pues entonces si es verdad lo que investigue :(

otra solucion que he rebuscado es lo siguiente, en la unit tengo el objeto del formulario y el hilo, si comparto una variable global alli puedo compartir la informacion entre los dos objetos.

Solo queria asegurarme si mi resultados eran correctos porq nunca he trabajado con hilos

xEsk 09-11-2007 15:36:47

Editado: veo que ya te han propuesto una solución parecida a esta... Ops! :P


Si realmente necesitas llamar el execute con parámetros, entonces emula el exeute con un proceso tuyo, con lo cual sí podrás pasarle parámetros...

Ejemplo:

Código Delphi [-]
// variable declarada en la sección private de la classe TMiThread
FnIdx: Integer;

// implementación de tu propio execute
procedure TMiThread.MiExecute(nIdx: integer);
begin
  FnIdx:=nIdx;
  Execute;
end;

// implementación del execute
procedure TMiThread.Execute;
begin
  if FnIdx then
    // bla bla bla!
end;

El código puede tener alguna errata, porqué lo he hecho de memoria sin probarlo xD Pero seguro que entiendes la idea xD

Saludos.

eduarcol 09-11-2007 15:43:22

gracias Xesk, estaba pensando en algo similar. He quedado en algo como esto:

Código Delphi [-]
unit unPricipal;

***

type

  //Hilo que compara los MD5 de los archivos
  TCompararMd5 = class(TThread)
     protected
        procedure Execute; override;
  end;

  //Formulario de soporte visual
  TfrActualizador = class(TForm)
    ***
  private
    { Private declarations }
    ***
  public
    { Public declarations }
    ***
  end; 

var
  nIdx: Integer;

//Compara los MD5 del archivo local y web y devuelve true o false
procedure TCompararMd5.Execute;
var
   aStream: TMemoryStream;
   cLocal: String;
   cWeb: TStringList;
   nIndice: Integer;
begin
   inherited;
   //Toma el MD5 del archivo local
   nIndice := nIdx; //Toma el valor de nIdx para que al ejecutarse otro hilo asegurarse que continua el mismo valor
   aStream := TMemoryStream.Create;
   cWeb    := TStringList.Create;
   try
      cLocal := AnsiUpperCase(MD5Sum(cRutaLocal.Strings[nIndice] + '\' + cArchivo.Strings[nindice]));
      if (Get(cHtml.Strings[nIndice] + '/pMd5.php?archivo=' + cArchivo.Strings[nIndice], aStream)) and (cLocal <> '') then
      begin
         aStream.Position:= 0; // <-- Hay que rebobinar el stream :-D
         cWeb.LoadFromStream(aStream);
         cWeb.Strings[0] := AnsiupperCase(cWeb.Strings[0]);
         //Compara el md5 del local con el web
         Resultado := cLocal = cWeb.Strings[0];
      end
      else
         Resultado := False;
   finally
      FreeandNil(aStream);
      FreeandNil(cWeb);
   end;
end;

*****

//Procedimiento donde se crea y se llama el hilo
procedure TfrActualizador.pActualizar(nIndice: Integer);
var
   cUrl, cRuta: String;
   thcMd5: TCompararMd5;
begin
   //Crea el hilo para comparar los MD5
   thcMd5 := TCompararMd5.Create(True);
   nIdx := nIndice;
   thcMd5.Resume;
   //Actualiza el sistema desde internet
   if not Resultado then
   begin
      //Descargar el archivo de la web
      cUrl := cHtml.Strings[nIndice] + '/' + cArchivo.Strings[nIndice];
      cRuta := cRutaLocal.Strings[nIndice] + '\' + cArchivo.Strings[nIndice];
      Bajar(cUrl, cRuta);
   end;
end;

******

end.

Lepe 09-11-2007 15:53:18

Código Delphi [-]
var
  nIdx: Integer;

¿no debería ser así?:
Código Delphi [-]
threadvar  // ojito a la palabra reservada de delphi.
  nIdx: Integer;

Si es una variable que va a usarse dentro de un Thread, debe ser ThreadSafe.

Aunque no veo el asunto claro. Estas creando una clase TCompararMd5 que a partir de un índice abre un archivo. ¿no sería mejor crear una propiedad en el Thread llamada Filename? así no se comparte información entre el hilo y su padre, además nos permitiría reusar la clase sin modificarla.

Saludos

Lepe 09-11-2007 16:02:22

No termino de comprender si nIdx debe compartir su valor entre los diferentes hilos o no, mejor revisa tú mismo si debe ser threadvar o no.

Saludos

eduarcol 09-11-2007 16:05:59

Disculpa la demora pero estaba revisando la ayuda acerca de threadvar y si es lo que necesito, muchisimas gracias


La franja horaria es GMT +2. Ahora son las 14:16: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