Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2005.06.06;
Скачать: [xml.tar.bz2];

Вниз

idHTTP при работе в потоке   Найти похожие ветки 

 
leonidus   (2005-03-06 13:01) [0]

Не понимаю почему компонент idHTTP крайне нестабильно работает в потоках (многие документы недокачиваются, получается куча документов размером окого килобайта). В связи с обсуждением сходных проблем с потоками в параллельной ветке в основных вопросах этого форума, вопрос: если компоненты idHTTP (у меня их четыре) лежат на форме, я что не могу запустить их работу в потоке, нужно их обязательно создавать в run-tim`е, в этом проблема ?


 
leonidus   (2005-03-06 23:12) [1]

Поможите приз!


 
leonidus   (2005-03-06 23:12) [2]

Поможите приз!


 
Reindeer Moss Eater ©   (2005-03-07 01:32) [3]

я что не могу запустить их работу в потоке, нужно их обязательно создавать в run-tim`е,
Какая связь между созданием в рантайм и работой в потоках?
Ни малейшей.


 
Zelius ©   (2005-03-07 15:18) [4]

Можешь спокойно их юзать в потоках, только каждый в своем одном. Смотри ошибки, какие возвращаются и анализируй их.


 
leonidus ©   (2005-03-07 22:26) [5]

Проблема вот в чем. На форме пять компонентов idHTTP, первый работает в основном потоке, и при его работе ни разу не наблюдалось недокачки документов или каких-то иных сбоев, четыре других компонента работают в потоках и при их работе такие сбои обнаруживаются постоянно, причем чем шире канал для скачиания тем чаше ошибки себя проявляют. При модемном соединении, довольно редко, при работе из локальной сети через мегабитный канал в интерент, они вообще толком не работают, скачают по 200-500 байт и все, в то же время первый компонент который работает в основном потоке все качает нормально. Поэтому я и грешу на поточность, может тут какие-то хитрости есть именно с компонентами Инди?


 
Mim2   (2005-03-07 22:37) [6]

Очень много работаю с этим компонентом в многопоточных приложениях и ни разу ни утечек памяти (на которые тоже грешат люди) ни недокачек небыло. Может имеет смысл задуматься о кудряшках на руках?


 
Reindeer Moss Eater ©   (2005-03-08 03:20) [7]

Поэтому я и грешу на поточность, может тут какие-то хитрости есть именно с компонентами Инди?

Лучше грешить на свой код. Полезнее.


 
leonidus ©   (2005-03-09 08:24) [8]

>Mim2 а можно маленький примерик, хотя бы с двумя потоками?


 
Reindeer Moss Eater ©   (2005-03-09 10:42) [9]

Программирование TidHTTP в потоках ничем не отличается от такого же не в потоках (тем более, что все равно главный поток - это тот же самый поток, только основной).
У компонента "чудесным образом" не "вырастают" новые методы и свойства если он используется во вторичном потоке.
Если же вопрос касается вторичных потоков вообще, то при чем здесь конференция "Сети"?


 
Zelius ©   (2005-03-09 12:25) [10]

Хотя, есть нюанс, используешь ли ты AntiFreeze?


 
Reindeer Moss Eater ©   (2005-03-09 12:43) [11]

Антифиз (или его отсутствие) каким образом может быть причиной описаной проблемы?


 
leonidus ©   (2005-03-09 13:55) [12]

Антифриз установлен, кстати у него свойстов IdleTimeOut у меня установлено в 10, там вообще что как настраивается?


 
Zelius ©   (2005-03-09 19:32) [13]

Я с ним не работал, а сейчас посмотрел - вроде все с ним в порядке в многоптоочности.

Все же, может там ошибка какая в потоке присходит?


 
leonidus ©   (2005-03-11 08:56) [14]

Пожалуйста если кто делал многопоточне приложения с idHTTP откликнитесь в приват.


 
leonidus ©   (2005-03-18 13:42) [15]

Написал небольшую тестовую программу реализующую 4-х поточную закачку документов компонентами idHTTP. На форме лежит 4 компонента idHTTP: HTTP1,HTTP2,HTTP3,HTTP4, компонент IdAntiFreeze1, два Memo, в первом 4 строки заполнено ссылками которые качаем:
http://www.lib.ru/
http://www.lib.ru/PROZA/
http://www.lib.ru/INPROZ/
http://www.lib.ru/RUFANT/

второй Memo будет содержать лог работы программы, также четыре Edit`а для установки параметров прокси-сервера и кнопка Button1 - "Старт".

Вот код:
  TThread1 = class(TThread)
  private
  protected
    procedure Execute; override;
  public
   URL: string;
  end;

  TThread2 = class(TThread)
  private
  protected
    procedure Execute; override;
  public
   URL: string;
  end;

  TThread3 = class(TThread)
  private
  protected
    procedure Execute; override;
  public
   URL: string;
  end;

  TThread4 = class(TThread)
  private
  protected
    procedure Execute; override;
  public
   URL: string;
  end;

var
 t1:TThread1;
 t2:TThread2;
 t3:TThread3;
 t4:TThread4;

begin

procedure TThread1.Execute;
var
f_stream:tfilestream;
error:boolean;
begin
form1.memo2.lines.add("1-й поток запущен");
f_stream:=tfilestream.Create("D:\WebTransporter\Exp\idHTTP\download\1.html",fmCreate);

try
form1.HTTP1.Get(t1.url,f_stream);
except
on E: Exception do error:=true;
end;

if error then
begin
 try
  form1.HTTP1.DisconnectSocket;
 finally
  f_stream.Free;
 end;
 form1.memo2.lines.add("ошибка в 1-м потоке");
end
 else f_stream.Free;
end;

procedure TThread2.Execute;
var
f_stream:tfilestream;
error:boolean;
begin
form1.memo2.lines.add("2-й поток запущен");
f_stream:=tfilestream.Create("D:\WebTransporter\Exp\idHTTP\download\2.html",fmCreate);

try
form1.HTTP2.Get(t2.url,f_stream);
except
on E: Exception do error:=true;
end;

if error then
begin
 try
  form1.HTTP2.DisconnectSocket;
 finally
  f_stream.Free;
 end;
 form1.memo2.lines.add("ошибка во 2-м потоке");
end
 else f_stream.Free;
end;

procedure TThread3.Execute;
var
f_stream:tfilestream;
error:boolean;
begin
form1.memo2.lines.add("3-й поток запущен");
f_stream:=tfilestream.Create("D:\WebTransporter\Exp\idHTTP\download\3.html",fmCreate);

try
form1.HTTP3.Get(t3.url,f_stream);
except
on E: Exception do error:=true;
end;

if error then
begin
 try
  form1.HTTP3.DisconnectSocket;
 finally
  f_stream.Free;
 end;
 form1.memo2.lines.add("ошибка во 3-м потоке");
end
 else f_stream.Free;
end;

procedure TThread4.Execute;
var
f_stream:tfilestream;
error:boolean;
begin
form1.memo2.lines.add("4-й поток запущен");
f_stream:=tfilestream.Create("D:\WebTransporter\Exp\idHTTP\download\4.html",fmCreate);

try
form1.HTTP4.Get(t4.url,f_stream);
except
on E: Exception do error:=true;
end;

if error then
begin
 try
  form1.HTTP4.DisconnectSocket;
 finally
  f_stream.Free;
 end;
 form1.memo2.lines.add("ошибка во 4-м потоке");
end
 else f_stream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
//запускаем закачку
begin
http1.ProxyParams.ProxyServer:=Edit3.Text;
http1.ProxyParams.ProxyPort:=strtoint(Edit4.Text);
http1.ProxyParams.ProxyUsername:=edit1.Text;
http1.ProxyParams.ProxyPassword:=edit2.Text;

http2.ProxyParams.ProxyServer:=Edit3.Text;
http2.ProxyParams.ProxyPort:=strtoint(Edit4.Text);
http2.ProxyParams.ProxyUsername:=edit1.Text;
http2.ProxyParams.ProxyPassword:=edit2.Text;

http3.ProxyParams.ProxyServer:=Edit3.Text;
http3.ProxyParams.ProxyPort:=strtoint(Edit4.Text);
http3.ProxyParams.ProxyUsername:=edit1.Text;
http3.ProxyParams.ProxyPassword:=edit2.Text;

http4.ProxyParams.ProxyServer:=Edit3.Text;
http4.ProxyParams.ProxyPort:=strtoint(Edit4.Text);
http4.ProxyParams.ProxyUsername:=edit1.Text;
http4.ProxyParams.ProxyPassword:=edit2.Text;

t1 := TThread1.Create(true);
t1.URL :=memo1.Lines.Strings[0];
t1.Resume;

t2 := TThread2.Create(true);
t2.URL :=memo1.Lines.Strings[1];
t2.Resume;

t3 := TThread3.Create(true);
t3.URL :=memo1.Lines.Strings[2];
t3.Resume;

t4 := TThread4.Create(true);
t4.URL :=memo1.Lines.Strings[3];
t4.Resume;
end;

В результате выкачиваются все файлы... но в логе получаю:
2-й поток запущен
4-й поток запущен
3-й поток запущен
1-й поток запущен
ошибка во 2-м потоке
ошибка в 1-м потоке
ошибка в 3-м потоке
ошибка в 4-м потоке

Но, при этом все 4 документа скачиваются нормально, совершенно полностью. в чем же дело, если все нормально, то почему срабатывает исключительная ситуация в блоках типа:

try
form1.HTTP1.Get(t1.url,f_stream);
except
on E: Exception do error:=true;
end;

???

Все тесттровалось из локальной сети с доступом в инет через прокси-сервер.


 
Digitman ©   (2005-03-18 14:08) [16]


> procedure TThread1.Execute;
> ...
> form1.memo2.lines.add("1-й поток запущен");


ну и какого ляда ты обращаешься в VCL-объекту в доп.трэде ?
грешишь на TIdHTTP, а до него и дело-то вообще не доходит - лажа видна уже при обращении к обычному TMemo ...


 
leonidus ©   (2005-03-18 14:47) [17]

ну да, намек я понял, только что-то с synchronize не пойму что за трабла, пишу:

....
  TThread1 = class(TThread)
  private
  protected
    procedure Execute; override;
    procedure showlog(st:string);
  public
   URL: string;
  end;

....

procedure TThread1.showlog(st:string);
begin
form1.memo2.lines.add(st);
end;

procedure TThread1.Execute;
var
f_stream:tfilestream;
error:boolean;
begin
synchronize(showlog("1-й поток запущен"));
f_stream:=tfilestream.Create("D:\WebTransporter\Exp\idHTTP\download\1.html",fmCreate);
...

компилятор ругается на строчку synchronize(showlog("1-й поток запущен"));, прямое указание TThread1.synchronize(showlog("1-й поток запущен")); тоже не катит.


 
Alexander Panov ©   (2005-03-18 14:57) [18]

1. Почитай статьи на сайте по работе с потоками, примеры в демках посмотри.

А вот пример создания в ран-тайме запроса.


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, IdIntercept, IdLogBase, IdLogDebug, IdBaseComponent,
 IdComponent, IdTCPConnection, IdTCPClient, IdHTTP;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

   TTrafic=record
     InBytes,OutBytes: Integer;
   end;

   TNetParm=record
     Query: String;
     UserName: String;
     Password: String;
     BasicAuth: Boolean;
     ProxyAddr: String;
     ProxyPort: Integer;
     ProxyUserName: String;
     ProxyPassword: String;
     PostQuery: String;
     Cookies: String;         //Lines with #13#10
   end;

   TNetResult=record
     ResCode: Integer;
     ResMsg: String;
     ResHead: String;
     ResBody: String;
     Trafic: TTrafic;
   end;

 TGetHTTP=class
 private
   IH: TIdHTTP;
   IL: TIdLogDebug;
   FRecv,FSent: Integer;
   BufRecv: String;
   procedure LogReceive(ASender: TIdConnectionIntercept;
     AStream: TStream);
   procedure LogSend(ASender: TIdConnectionIntercept;
     AStream: TStream);
   procedure SetParam(Parm: TNetParm);
 public
   constructor Create;
   destructor Destroy; override;
   function Get(Parm: TNetParm): TNetResult;
   function Post(Parm: TNetParm): TNetResult;
 end;

var
 Form1: TForm1;
 HT: TGetHTTP;

implementation

{$R *.dfm}

{ TThrHTTP }

constructor TGetHTTP.Create;
begin
 inherited Create;
 IH := TIdHTTP.Create(nil);
 IL := TIdLogDebug.Create(nil);
 IH.Intercept := IL;
 IL.OnReceive := LogReceive;
 IL.OnSend := LogSend;
 IL.Active := True;
end;

destructor TGetHTTP.Destroy;
begin
 IL.Free;
 IH.Free;
 inherited;
end;

function TGetHTTP.Get(Parm: TNetParm): TNetResult;
begin
 SetParam(Parm);
 try
   Result.ResBody := IH.Get(Parm.Query);
   Result.ResHead := Copy(BufRecv,1,Pos(#13#10#13#10,BufRecv)-1);
 except
 end;
 Result.ResCode := IH.ResponseCode;
 Result.ResMsg := IH.ResponseText;
 Result.Trafic.InBytes := FRecv;
 Result.Trafic.OutBytes := FSent;
end;

procedure TGetHTTP.LogReceive(ASender: TIdConnectionIntercept;
 AStream: TStream);
var
 s: String;
begin
 SetLength(s,AStream.Size);
 AStream.Read(s[1],AStream.Size);
 BufRecv := BufRecv + s;
 FRecv := FRecv+AStream.Size;
end;

procedure TGetHTTP.LogSend(ASender: TIdConnectionIntercept;
 AStream: TStream);
begin
 FSent := FSent+AStream.Size;
end;

function TGetHTTP.Post(Parm: TNetParm): TNetResult;
var
 tL: TStringList;
begin
 SetParam(Parm);
 tL := TStringList.Create;
 try
   tL.Text := Parm.PostQuery;
   try
     Result.ResBody := IH.Post(Parm.Query,tL);
     Result.ResHead := Copy(BufRecv,1,Pos(#13#10#13#10,BufRecv)-1);
   except
   end;
 finally
   tL.Free;
 end;
 Result.ResCode := IH.ResponseCode;
 Result.ResMsg := IH.ResponseText;
 Result.Trafic.InBytes := FRecv;
 Result.Trafic.OutBytes := FSent;
end;

procedure TGetHTTP.SetParam(Parm: TNetParm);
begin
 IH.Request.Username := Parm.UserName;
 IH.Request.Password := Parm.Password;
 IH.Request.BasicAuthentication := Parm.BasicAuth;
 IH.ProxyParams.ProxyPort := Parm.ProxyPort;
 IH.ProxyParams.ProxyServer := Parm.ProxyAddr;
 IH.ProxyParams.ProxyUsername := Parm.ProxyUserName;
 IH.ProxyParams.ProxyPassword := Parm.ProxyPassword;
 IH.Request.CustomHeaders.Text := Parm.Cookies;
 IH.Request.UserAgent := "IE?";
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 parm: TNetParm;
 Res: TNetResult;
begin
 HT := TGetHTTP.Create;
 Parm.Query := Edit1.Text;
 Res := HT.Get(parm);
 Memo1.Lines.Text := Res.ResBody;
 HT.Free;
end;

end.



 
leonidus ©   (2005-03-18 15:17) [19]

> Alexander Panov  спасибо за код, сейчас посмотрю, однако подправил свой код с учетом синхронизации, получилось вот что (это для одного потока, остальные подобный):

  TThread1 = class(TThread)
  private
  protected
    procedure Execute; override;
    procedure showlog;
  public
   URL: string;
   log: string;
  end;

procedure TThread1.showlog;
begin
form1.memo2.lines.add(t1.log);
end;

procedure TThread1.Execute;
var
f_stream:tfilestream;
error:boolean;
begin
t1.log:="1-й поток запущен";
synchronize(showlog);

f_stream:=tfilestream.Create("D:\WebTransporter\Exp\idHTTP\download\1.html",fmCreate);

//Пытаемся получить http-документ
try
form1.HTTP1.Get(t1.url,f_stream);
except
on E: Exception do error:=true;
end;

//ошибка в потоке после оператора Get
if error then
begin
 try
  form1.HTTP1.DisconnectSocket;
 finally
  f_stream.Free;
 end;
 t1.log:="ошибка в 1-м потоке";
 synchronize(showlog);

end
 else f_stream.Free;
end;

В результате в логе:

1-й поток запущен
2-й поток запущен
3-й поток запущен
4-й поток запущен
ошибка в 1-м потоке
ошибка во 2-м потоке
ошибка в 4-м потоке
ошибка в 3-м потоке

в общем-то без разницы:(


 
Alexander Panov ©   (2005-03-18 15:21) [20]

тогда вот пример на основе пред. класса:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, IdIntercept, IdLogBase, IdLogDebug, IdBaseComponent,
 IdComponent, IdTCPConnection, IdTCPClient, IdHTTP;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

   TTrafic=record
     InBytes,OutBytes: Integer;
   end;

   TNetParm=record
     Query: String;
     UserName: String;
     Password: String;
     BasicAuth: Boolean;
     ProxyAddr: String;
     ProxyPort: Integer;
     ProxyUserName: String;
     ProxyPassword: String;
     PostQuery: String;
     Cookies: String;         //Lines with #13#10
   end;

   TNetResult=record
     ResCode: Integer;
     ResMsg: String;
     ResHead: String;
     ResBody: String;
     Trafic: TTrafic;
   end;

 TGetHTTP=class
 private
   IH: TIdHTTP;
   IL: TIdLogDebug;
   FRecv,FSent: Integer;
   BufRecv: String;
   procedure LogReceive(ASender: TIdConnectionIntercept;
     AStream: TStream);
   procedure LogSend(ASender: TIdConnectionIntercept;
     AStream: TStream);
   procedure SetParam(Parm: TNetParm);
 public
   constructor Create;
   destructor Destroy; override;
   function Get(Parm: TNetParm): TNetResult;
   function Post(Parm: TNetParm): TNetResult;
 end;

 TThrHTTP=class(TThread)
 private
   FQ: TGetHTTP;
   FQuery: String;
   FLogControl: TMemo;
   FMessage: String;
   procedure Display;
 protected
   procedure Execute; override;
 public
   constructor Create(aQuery: String;aLogControl: TMemo);
   destructor Destroy;override;
 end;

var
 Form1: TForm1;
 HT: TThrHTTP;

implementation

{$R *.dfm}

{ TThrHTTP }

constructor TGetHTTP.Create;
begin
 inherited Create;
 IH := TIdHTTP.Create(nil);
 IL := TIdLogDebug.Create(nil);
 IH.Intercept := IL;
 IL.OnReceive := LogReceive;
 IL.OnSend := LogSend;
 IL.Active := True;
end;

destructor TGetHTTP.Destroy;
begin
 IL.Free;
 IH.Free;
 inherited;
end;

function TGetHTTP.Get(Parm: TNetParm): TNetResult;
begin
 SetParam(Parm);
 try
   Result.ResBody := IH.Get(Parm.Query);
   Result.ResHead := Copy(BufRecv,1,Pos(#13#10#13#10,BufRecv)-1);
 except
 end;
 Result.ResCode := IH.ResponseCode;
 Result.ResMsg := IH.ResponseText;
 Result.Trafic.InBytes := FRecv;
 Result.Trafic.OutBytes := FSent;
end;

procedure TGetHTTP.LogReceive(ASender: TIdConnectionIntercept;
 AStream: TStream);
var
 s: String;
begin
 SetLength(s,AStream.Size);
 AStream.Read(s[1],AStream.Size);
 BufRecv := BufRecv + s;
 FRecv := FRecv+AStream.Size;
end;

procedure TGetHTTP.LogSend(ASender: TIdConnectionIntercept;
 AStream: TStream);
begin
 FSent := FSent+AStream.Size;
end;

function TGetHTTP.Post(Parm: TNetParm): TNetResult;
var
 tL: TStringList;
begin
 SetParam(Parm);
 tL := TStringList.Create;
 try
   tL.Text := Parm.PostQuery;
   try
     Result.ResBody := IH.Post(Parm.Query,tL);
     Result.ResHead := Copy(BufRecv,1,Pos(#13#10#13#10,BufRecv)-1);
   except
   end;
 finally
   tL.Free;
 end;
 Result.ResCode := IH.ResponseCode;
 Result.ResMsg := IH.ResponseText;
 Result.Trafic.InBytes := FRecv;
 Result.Trafic.OutBytes := FSent;
end;

procedure TGetHTTP.SetParam(Parm: TNetParm);
begin
 IH.Request.Username := Parm.UserName;
 IH.Request.Password := Parm.Password;
 IH.Request.BasicAuthentication := Parm.BasicAuth;
 IH.ProxyParams.ProxyPort := Parm.ProxyPort;
 IH.ProxyParams.ProxyServer := Parm.ProxyAddr;
 IH.ProxyParams.ProxyUsername := Parm.ProxyUserName;
 IH.ProxyParams.ProxyPassword := Parm.ProxyPassword;
 IH.Request.CustomHeaders.Text := Parm.Cookies;
 IH.Request.UserAgent := "IE?";
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TThrHTTP.Create("http://www.lib.ru/",Memo1);
 TThrHTTP.Create("http://www.lib.ru/",Memo1);
 TThrHTTP.Create("http://www.lib.ru/",Memo1);
 TThrHTTP.Create("http://www.lib.ru/",Memo1);
end;

{ TThrHTTP }

constructor TThrHTTP.Create(aQuery: String;aLogControl: TMemo);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FQ := TGetHTTP.Create;
 FQuery := aQuery;
 FLogControl := aLogControl;
 Resume;
end;

destructor TThrHTTP.Destroy;
begin
 FQ.Free;
 inherited;
end;

procedure TThrHTTP.Display;
begin
 FLogControl.Lines.Add(FMessage);
end;

procedure TThrHTTP.Execute;
var
 NP: TNetParm;
 NR: TNetResult;
begin
 FMessage := "Старт потока";
 Synchronize(Display);
 NP.Query := FQuery;
 NR := FQ.Get(NP);
 FMessage := "Запрос выполнен";
 Synchronize(Display);
end;

end.


 
leonidus ©   (2005-03-18 15:24) [21]

>Alexander Panov я в рантайме idHTTP не создаю, мне удобнее все настроить в design-time, а разве есть разница?


 
leonidus ©   (2005-03-18 15:25) [22]

щас попробую, но почему же мой код не работает?


 
leonidus ©   (2005-03-18 15:42) [23]

>Alexander Panov, код работает, еще раз спасибо. но все таки хочется что бы можно было не создавать компоненты в run-time а использовать уже существующие, и кстали кк в Вашем коде получить скачанный файла на диске?


 
Alexander Panov ©   (2005-03-18 15:48) [24]

leonidus ©   (18.03.05 15:42) [23]
и кстали кк в Вашем коде получить скачанный файла на диске


  TNetResult=record
    ResCode: Integer;     Код возврата
    ResMsg: String;       Сообщение об ошибке(напр. 200 OK)
    ResHead: String;      Полученный заголовок
    ResBody: String;      Полученная страница
    Trafic: TTrafic;      Объем трафика
  end;


 
leonidus ©   (2005-03-18 16:35) [25]

TThrHTTP=class(TThread)
 private
   FQ: TGetHTTP;
   FQuery: String;
   FLogControl: TMemo;
   FMessage: String;
   procedure Display;
 protected
   procedure Execute; override;
 public
   constructor Create(aQuery: String;aLogControl: TMemo);
   destructor Destroy;override;
   procedure Break;
 end;


 
leonidus ©   (2005-03-19 23:53) [26]

>Alexander Panov, код ваш мучаю второй день - намучил уже много:)

Появился ряд вопросов:

1. Как остановить закачку всех потоков и выбранного?
2. Специально следил через диспетчер задач за тем как программа создает и убивает потоки - все корректно, всязи с чем вопрос, как поток узнает что поза вызвать дектруктор?
3. У idHTTP есть очень нужное мне событие OnWork, в нем удобно считать скорость закачки, отображать прогресс закачки, там же планирую ставить ограничение на скорость скачивания, как его прикрутить к созданному в рантайме компоненту? Я делаю так,
при объявлении класса добавляю procedure OnWork:

TGetHTTP=class
private
  HTTP_component: TIdHTTP;
  Log_component: TIdLogDebug;

  FRecv,FSent: Integer;
  BufRecv: String;
  procedure LogReceive(ASender: TIdConnectionIntercept;
    AStream: TStream);
  procedure LogSend(ASender: TIdConnectionIntercept;
    AStream: TStream);

  procedure OnWork(Sender: TObject; AWorkMode: TWorkMode;
 const AWorkCount: Integer);
 ...
 ...


в конструкторе TGetHTTP, добавляю строчку: HTTP_component.OnWork:=OnWork, получаем:

constructor TGetHTTP.Create;
begin
inherited Create;
HTTP_component := TIdHTTP.Create(nil);
HTTP_component.OnWork:=OnWork;
...
end;

и потом создаю саму процедуру:
procedure TGetHTTP.OnWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
end;

но вот тут то и проблема, мне нужно передать потоку значение AWorkCount для того что бы знать сколько скачано байт, данным экземпляром класса и зная общий размер документа отобразить прогресс закачки, но как осуществить передачу этой информации не понятно совершенно.

4. Зачем нужен Log_component, какой от него прок?
5. Почему в вашем коде не используется idAntifrezee, или он нужен только если idHTTP лежат не форме?
6. У меня 9-я Indy, помню в 8-й ConnectionTimeout работал очень глючно, сейчас можно на него положиться? И как должен повести себя поток в котором истечет период ожидания?

Простите за такую массу вопросов, просто начал разбиратся, стало крайне интересно, я раньше особенно потоками не занимался, а тут еще и нелюбимый мной ООП во всей своей красе:)



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2005.06.06;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.011 c
1-1116509769
Object
2005-05-19 17:36
2005.06.06
Как найти запись в XML без аттрибутов?


1-1116764311
Isaev
2005-05-22 16:18
2005.06.06
TButton


3-1114750485
NewAtoL
2005-04-29 08:54
2005.06.06
DbExpress и DBLookupCombobox


3-1115092792
hawkins
2005-05-03 07:59
2005.06.06
Как у interbase базы данных определить диалект с которым она созд


1-1116835490
Stanislav
2005-05-23 12:04
2005.06.06
Вызов редактора свойств в run time





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский