Tema: Multithread
Ver Mensaje Individual
  #1  
Antiguo 11-05-2012
angelp4492 angelp4492 is offline
Miembro
 
Registrado: dic 2007
Posts: 99
Reputación: 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 10:43:36.
Responder Con Cita