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 11-05-2012
angelp4492 angelp4492 is offline
Miembro
 
Registrado: dic 2007
Posts: 99
Poder: 0
angelp4492 cantidad desconocida en este momento
Multithread

Buenos días, siguiendo un ejemplo de downloader de Neftali me he creado esta unidad de descarga

Código Delphi [-]

unit UnitDownload;

interface
   uses
  Dialogs,SysUtils,Classes, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,DateUtils;

type
  TIdHTTPThread = class(TThread)    //DEFINIMOS EL thread de decarga
  private
    //definimos las variables del thread
    FURL: AnsiString;  //dirección de descarga
    FFilename: AnsiString; //nombre del fichero de descarga
    velocidad,transferencia,tiempo,size,porcentaje: string; // velocidad,transferencia de descarga y tamaño del fichero
    posProgress,maxProgress : Int64; // datos para la barra de progreso
    Proxyport: Int64;        //datos para el proxy
    ProxyServer:AnsiString;
    IdHTTP: TIdHTTP;       //objeto TidHTTP
    ProxySI : Boolean;     // para comprobar si la conexión es por proxy
    threadterminado : Boolean;   //para esperar que termine el thread
    parar : Boolean; //parar el thread.
    TID : Integer; //identificador del thread
    //definimos los procedimientos del thread
    procedure OnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
    procedure OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
    procedure OnWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    procedure cancel;
    procedure Updatelabel;
    procedure UpdaProgressbar;
    procedure FinThread;
     procedure IniThread;
     procedure EndNotify;
  public
    //constructor del thread para pasarle parámetros.
     constructor Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:Integer);
    Destructor Destroy; override;
    //property Url: AnsiString read FURL write FUrl;
    //property Filename: AnsiString read FFilename write FFilename;
    //property Proxy_SI : Boolean read ProxySI write ProxySI;
    //property Proxy_Port: Int64 read   Proxyport write Proxyport;
    //property Proxy_Server: AnsiString read ProxyServer write ProxyServer;
    property terminado :Boolean read Threadterminado write Threadterminado;
    // con la propiedad property intercambio información con el thread y el formulario
    property parate : Boolean read parar write parar;
  protected
    procedure Execute; override;
  end;

implementation
  uses Unit1; // aqui ponemos la unidad desde donde será ejecutado el thread.

  constructor TIdHTTPThread.Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:integer);
begin
  inherited Create(false);
   FreeOnTerminate := True;
   FURL :=sFUrl;
   FFilename:=destino;
   ProxySI:=Proxy;
   Proxyport:=sProxyport;
   ProxyServer:=sProxyserver;
   TID:=sTID



end;

destructor TIdHTTPThread.Destroy;
begin
  IdHTTP.Free;
  
  inherited;
end;
procedure TIdHTTPThread.cancel;
begin
  if (IdHTTP.Connected) and (parar = True) then
  IdHTTP.Disconnect;
end;
procedure TIdHTTPThread.Execute;
var
  fs: TFileStream;
  idHTTP : TidHttp;
begin
     Synchronize(IniThread);
    idHttp:= Tidhttp.create(nil);
    if ProxySI = true then
       begin
         IdHTTP.ProxyParams.ProxyServer:=ProxyServer;
         IdHTTP.ProxyParams.ProxyPort:=Proxyport;
       end;
         idHTTP.HandleRedirects := True;
         idHTTP.ReadTimeout := 30000;
         IdHTTP.ProtocolVersion:= pv1_0;
         idHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)';
         IdHTTP.OnWork :=  Onwork;
         IdHTTP.OnWorkBegin:=OnWorkBegin;
         IdHTTP.OnWorKEnd:=OnWorkEnd;
         //ShowMessage('proxy='+ProxyServer);
         //ShowMessage(FFilename);
         //ShowMessage(furl);
         fs := TFileStream.Create(FFilename, fmCreate);
    try
        IdHTTP.Get(FUrl, fs);

     finally
        fs.Free;


        Synchronize(EndNotify);
     end;

end;



    //Poner estado de valores cuando se empieza a descargar
procedure TIdHTTPThread.OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
begin
   posProgress:= 0;
  if AWorkMode = wmRead then //uniquement quand le composant recoit des données
   begin
      maxProgress := AWorkCountMax; //Maximum = taille du soft à télécharger

      posProgress := 0; //Position à zéro
  end;
   if AWorkMode = wmRead then //uniquement quand le composant recoit des données
   begin
      velocidad := 'Descarga: 0 Kb/s ';
      FStartDate := Now; //enregistre la date
      //Application.ProcessMessages; //Evite que l'appli soit "gelée"
 end;
 Synchronize(Updatelabel);
 Synchronize(Updaprogressbar);
end;




procedure TIdHTTPThread.OnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
  var
    ElapsedTime : Cardinal;
    n1,n2 : double;
begin
// Avanzando...

  if AWorkMode=wmRead then //quand on recoit des données
   begin
  
   posProgress := AWorkCount + 40;
     size := Format(' %s Mb',[FormatFloat('0.00',(maxProgress)/1024000)]);
     ElapsedTime := SecondsBetween(Now,FStartDate); //Calcule la vitesse de téléchargement
     if ElapsedTime>0 then
     begin
       velocidad := Format('Descarga: %s Kb/s',[FormatFloat('0.00',(AWorkCount/1024)/ElapsedTime)]);
       n1:=  (AWorkCount/1024000);
       n2:= (maxProgress/1024000);
      // velocidad := Format('Descarga: %s Kb/s',[FormatFloat('0.00',(AWorkCount*elapsedtime)/1024)]);

       transferencia:= Format('Descargado: %s Mb ',[FormatFloat('0.00',(AWorkCount/1024000))])+Format('De: %s Mb',[FormatFloat('0.00',(maxProgress)/1024000)]);;
       //lbldescarga.Caption:=lbldescarga.Caption+' de '+ Format('Descargado: %s Mb/s',[FormatFloat('0.00',(ProgressBar1.Max)/1024000)]);

       porcentaje:=Format('Porcentaje: %s',[FormatFloat('0',((AWorkCount*100)/maxprogress))])+'%';

       tiempo:=Format('Tiempo Restante %s ',[FormatDateTime('tt',((n2-n1)*elapsedtime))]);
       //Application.ProcessMessages;   //Evite que l'appli soi "givrée"

    end;

   end;
        //ShowMessage(IntToStr(aworkcount));
       Synchronize(Updatelabel);
       Synchronize(Updaprogressbar);
end;
procedure TIdHTTPThread.OnWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
  // Acabado
  maxProgress := 0;
  transferencia:='Descargando:';
  velocidad:='Descarga:';
   Synchronize(Updatelabel);
   Synchronize(Updaprogressbar);
end;
//procedimiento para actualizar las variables del form
//los llamamos con synchronize (nameprocedimiento=
procedure TIdHTTPThread.Updatelabel;
begin
Form1.UpdateLabel(velocidad,transferencia,tiempo,size,porcentaje);
end;

procedure TIdHTTPThread.UpdaProgressbar;
begin
  Form1.UpdateProgressbar(posProgress,maxProgress);
end;
procedure TIdHTTPThread.FinThread ;
begin
  form1.finthread:=True;
end;
procedure TIdHTTPThread.IniThread ;
begin
  form1.finthread:=false;
end;

procedure TIdHTTPThread.EndNotify;
begin
  Form1.eventhreadterminate(TID);
end;

end.



seguramente se podrá mejorar.
El problema es que esto me funciona cuando tengo un solo thread, pero como haria por ejemplo que es lo que quiero hacer para mandar los datos de descarga con un progressbar a un listview y en multithread. O sea un Multidownloader con listview y progressbar al estilo del Jdonwloader.

Última edición por angelp4492 fecha: 11-05-2012 a las 11:43:36.
Responder Con Cita
  #2  
Antiguo 11-05-2012
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
Recuerda poner títulos descriptivos a las preguntas, gracias
Responder Con Cita
  #3  
Antiguo 11-05-2012
Avatar de javier7ar
javier7ar javier7ar is offline
Miembro
 
Registrado: abr 2006
Ubicación: Argentina
Posts: 124
Poder: 18
javier7ar Va por buen camino
pero si eso que tenes ya es multithread! cada instancia que creas de esta clase es un thread; si creas 5 instancias vas a tener 5 threads!
lo unico que te faltaria es tener 5 barras de progreso, y alguna forma de decir que barra corresponde a que thread.
Cuando digo 5, pueden ser los que quieras
Si no es eso a lo que te referis, escribi un ejemplo de lo que necesitas, asi te podemos ayudar mejor
Saludos
Responder Con Cita
  #4  
Antiguo 11-05-2012
angelp4492 angelp4492 is offline
Miembro
 
Registrado: dic 2007
Posts: 99
Poder: 0
angelp4492 cantidad desconocida en este momento
Cita:
Empezado por javier7ar Ver Mensaje
pero si eso que tenes ya es multithread! cada instancia que creas de esta clase es un thread; si creas 5 instancias vas a tener 5 threads!
lo unico que te faltaria es tener 5 barras de progreso, y alguna forma de decir que barra corresponde a que thread.
Cuando digo 5, pueden ser los que quieras
Si no es eso a lo que te referis, escribi un ejemplo de lo que necesitas, asi te podemos ayudar mejor
Saludos

Si a eso exactamente me refiero, tengo una barra de progreso y cuando lanzo 5 thread todos me muestran los datos en la misma barra, y no se como poner los datos en sus correspondientes barras.
Responder Con Cita
  #5  
Antiguo 14-05-2012
Avatar de javier7ar
javier7ar javier7ar is offline
Miembro
 
Registrado: abr 2006
Ubicación: Argentina
Posts: 124
Poder: 18
javier7ar Va por buen camino
y tendrias que identificar cada thread, por ejemplo mandandole un nro cuando lo creas, entonces despues cuando el thread llama a actualizar el progressbar pasa su nro por parametro y el Form1 en base al nro que recibe actualiza uno u otro progressbar.
Seria algo asi:
Código Delphi [-]
constructor TIdHTTPThread.Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:integer; Nro:Integer);
begin
  inherited Create(false);
  FreeOnTerminate := True;
  FNro:=Nro;
...
y cuando llamas a actualizar la barra de progreso:
Código Delphi [-]
// y aca cambias esto:
Form1.UpdateProgressbar(posProgress,maxProgress);
// por esto:
Form1.UpdateProgressbar(posProgress,maxProgress,FNro);
y en el procedimiento UpdateProgressbar te fijas en el nro que te pasan por parametro y actualizas la barra que corresponde
Espero se entienda
Saludos
Responder Con Cita
  #6  
Antiguo 15-05-2012
angelp4492 angelp4492 is offline
Miembro
 
Registrado: dic 2007
Posts: 99
Poder: 0
angelp4492 cantidad desconocida en este momento
Siguiendo unos ejemplos que hay por la red y cambiando la forma que el thread manda información, usando WM_USER, me he creado una clase para controlor el thread.

En la recepción del mensaje del thread tengo esto.

Código Delphi [-]
Procedure Tform1.HTTPClientDownloadBeginWork(var Msg:TMessage);
    var
        uniqueid_: integer;
        totalbytes_: integer;
        i: integer;
    begin
        uniqueid_ := Msg.wparam;
        totalbytes_ := Msg.LParam;

        i := IndexOfDownloadableFile(uniqueid_);
        if i <> -1 then
        begin

           //ShowMessage(IntToStr(totalbytes_));
           form1.ProgressBar1.Position:=0;
           form1.ProgressBar1.Max:=totalbytes_;
           TTransferFile(DownloadList[i]).BytesDownloaded := TTransferFile(DownloadList[i]).BytesPreviouslyDownloaded;
           TTransferFile(DownloadList[i]).TotalFileSize := TTransferFile(DownloadList[i]).BytesPreviouslyDownloaded + totalbytes_;
           //TDownloadFile(DownloadaList[i]).State := si_Downloading_Animation1;
           TTransferFile(DownloadList[i]).ProgressBar.Position := 0;
           TTransferFile(DownloadList[i]).ProgressBar.Max := TTransferFile(downloadlist[i]).TotalFileSize;
           ListviewTransfer.Repaint;

        end;
    end;

donde TTransferfile y Tdownload file son clases para manejar la descarga y downloadlist una variable de tipo objectlist. el progressbar lo creo de esta manera.

Código Delphi [-]

procedure TTransferFile.addToView;
var
  RectProg: TRect;
begin
item := ListView.items.add;
item.Caption := Url;
Item.SubItems.Add('0 kb/s');
Item.SubItems.Add('');


//if es_descarga then Item.ImageIndex := 9
//else Item.ImageIndex := 10;
ProgressBar := TsProgressBar.Create(nil);
Item.Data := ProgressBar;
RectProg := Item.DisplayRect(drBounds);
RectProg.Left := RectProg.Left + ListView.Columns[0].Width;
RectProg.Right := RectProg.Left + ListView.Columns[1].Width;
ProgressBar.BoundsRect := RectProg;
progressBar.Parent := ListView;

end;
.

En totalbytes_ tengo el tamaño del fichero en bytes, el progressbar1 componente normal me lo acepta si problemas cuando pongo form1.progressbar1.max=totalbytes_

El problema que tengo es en esta linea

TTransferFile(DownloadList[i]).ProgressBar.Max := TTransferFile(downloadlist[i]).TotalFileSize;

me sale un error que solo acepta entre 0 y 65536. Alguna Idea.
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
Duda en Sockets MultiThread JesusRamirez Internet 3 21-08-2010 07:54:13
componente MultiFileDownloader multithread para bajar http y ftp en indy 10 softx2009 Internet 3 18-01-2010 17:17:47


La franja horaria es GMT +2. Ahora son las 22:36:32.


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