Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TidHTTP при работе в потоке [D6, WinXP]


leonidus ©   (2004-07-05 22:45:00) 

Есть код:

type
 TThread1 = class(TThread)
 private
   { Private declarations }
 protected
   procedure DoWork;
   procedure Execute; override;
 public
  URL: string;
 end;

 TThread2 = class(TThread)
 private
   { Private declarations }
 protected
   procedure DoWork;
   procedure Execute; override;
 public
  URL: string;
 end;

.....
.....

procedure TThread1.Execute;
begin
Synchronize(DoWork);
end;

procedure TThread2.Execute;
begin
Synchronize(DoWork);
end;

procedure TThread1.DoWork;
begin
form1.idHTTP1.Get(t1.url,'c:\1.txt');
end;

procedure TThread1.DoWork;
begin
form1.idHTTP2.Get(t2.url,'c:\2.txt');
end;

по клику на кнопке запускаю потоки

var
t1:TThread1;
t2:TThread2;
...
...
t1 := TThread1.Create(true);
t1.URL := turn[i];
t1.Resume;

t2 := TThread2.Create(true);
t2.URL := turn[i+1];
t2.Resume;
.....

в результате потоки качают не параллельно а один за другим, т.е. сначала первый потом второй. Что я делаю не так? И еще вопрос, как корректно убить поток, если закачка еще идет, t1.Terminate; выдает run-time error?


Digitman   (2004-07-08 15:39:00) [1]


> leonidus


и еще.

никто не спорит, что справочный материал (по классам и компонентам от Борланда в дан.случае) весьма скуден и порой не дает однозначных ответов на конкретные вопросы

Но ! Есть ведь исх.тексты этих классов .. и опять все сводится к необходимости анализировать эти тексты, дабы познать непознанное, коль есть желание и целеустремленность


Reindeer Moss Eater   (2004-07-08 15:26:00) [2]

Так вот.
До тех пор пока ты не начал предъявлять претензии к качеству ответов, никто тебе не ставил в вину качество твоих вопросов.
На них просто отвечали и все.


Digitman   (2004-07-08 15:26:00) [3]


> степени моего понимания данной проблемы


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


leonidus   (2004-07-08 15:12:00) [4]

Если бы я умел задавать симпатичные вопросы, то наверное сам бы смог на них ответить, а пока вопросы соответсвуют степени моего понимания данной проблемы


Reindeer Moss Eater   (2004-07-07 15:34:00) [5]

так понимаю что форумы для того и существуют что бы задавать вопросы...

Тебе их кто-то запрещал задавать?
Нет.
Тебе не нравятся ответы? А думаешь вопросы твои очень симпатичные?


leonidus   (2004-07-07 15:17:00) [6]

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


Digitman   (2004-07-07 08:10:00) [7]


> leonidus   (07.07.04 07:55) [12]


напрасно ты считаешь себя "униженным"..
RME прав по сути, даже если имел неосторожность высказаться в резком тоне ..

ну посуди сам - ведь код приведен для детального построчного анализа, со справочным материалом в руках, а твои вопросы в [7] говорят о том, что прежде чем их задавать ты даже не вник в этот код


leonidus   (2004-07-07 07:55:00) [8]

Спасибо всем, в особенности Digitman.

>Reindeer Moss Eater хочу вам сказать, что если вы хороший программист, то это не заначит, что надо унижать тех кто в этом деле не так силен, тем более что иногда приходится заниматься программированием не только программистам, но и обыным технарям.


Digitman   (2004-07-06 16:39:00) [9]


> leonidus   (06.07.04 15:47) [7]


> Я правильно понял, что операторы..
> выполнятся сразу один за другим и запустят два потока?


правильно

1. Никакой. см.[8],[9]
Вопрос про принудительное "убийство" ты не ставил изначально, поэтому в примере поток корректно "умирает" сам, при успешном выполнении - молча, при ошибке - выведя перед этим диалог с причиной ошибки
Про потоковый "суицид" читай справку о св-ве FreeOnTerminate

2. Обрати внимание на try..except в теле Execute() - ЛЮБЫЕ исключительные ситуации перехватываются и обрабатываются простейшим образом, освобождение же ресурсов безусловно осуществляется во вложенном блоке try..finally

вообще-то говоря, пример приведен для детального анализа его простейшего алгоритма, а не для подобных вопросов.. на то и пример


Reindeer Moss Eater   (2004-07-06 16:16:00) [10]

Ну и вообще зачем вызывать Terminate, если:

constructor TMyThread.Create(Host: String; Port: Integer; URL, FileName: String);
begin
...
FreeOnTerminate := True;
...
end;

"Для мебели"?

Зря все же тебе дали готовый пример. Не в прок.


Reindeer Moss Eater   (2004-07-06 16:11:00) [11]

TMyThread.Terminate
Тем более, что так писать безграмотно.

Terminate это метод, а не классовый метод.
Вызывать его надо у конкретного экземпляра, а не у класса


Reindeer Moss Eater   (2004-07-06 16:09:00) [12]

1. Никакой. Terminate не убивает потоки
2. Все исключения в потоке должны быть обработаны в потоке


leonidus   (2004-07-06 15:47:00) [13]

>Digitman спасибо за ответ.
Я правильно понял, что операторы
TMyThread.Create('vasya-pupkin.ru', 80, turn[i], 'c:\1.txt');
TMyThread.Create('petya-chainik.neru', 80, turn[i+1], 'c:\2.txt');
выполнятся сразу один за другим и запустят два потока? э

Тем не менее остается два вопроса: если я напишу TMyThread.Terminate то
1. какой из потоков я убъю, у меня же их два, или я в этом случае не смогу управлять каждым потоком в отдельности?
2. если поток будет работать т.е. TIdHTTP методом GET ведет закачку,  не произойдет ли run-time ошибки, или поток должен корректно исвободить свои ресурсы и заодно разорвать коннект установленый TIdHTTP и убить сам TIdHTTP?


Digitman   (2004-07-06 13:58:00) [14]

type
TMyThread = class(TThread)
private
  FIdHTTP: TIdHTTP;
  FURL: String;
  FFileName: String;
  FHost: String;
  FPort: Integer;
  FErr: String;
protected
  procedure Execute; override;
  procedure DoError;
public
  constructor Create(Host: String; Port: Integer; URL, FileName: String);
end;

.....

constructor TMyThread.Create(Host: String; Port: Integer; URL, FileName: String);
begin
FHost := Host;
FPort := Port;
FURL := URL;
FFilename := FileName;
inherited Create(True);
FreeOnTerminate := True;
Resume;
end;

procedure TMyThread.DoError;
begin
 ShowMessage(FErr);
end;

procedure TMyThread.Execute;
begin
try
 FIdHTTP := TIdHTTP.Create(nil);
 with FIdHTTP do
 try
   Host := FHost;
   Port := FPort;
   Connect;
   Get(FURL, FFileName);
 finally
   FIdHTTP.Free;
 end;
except
 on e: Exception do
  begin
    FErr := 'Исключение ' + e.ClassName + ' ' + e.Message + ' в потоке ' + IntToStr(ThreadId);
    Synchronize(DoError);
  end;
end;
end;

....

TMyThread.Create('vasya-pupkin.ru', 80, turn[i], 'c:\1.txt');
TMyThread.Create('petya-chainik.neru', 80, turn[i+1], 'c:\2.txt');


Reindeer Moss Eater   (2004-07-06 13:47:00) [15]

Synchronize- убери
URL передавай конструктору потока (или как - нибудь иначе)
После успешной закачки извещай основной поток о результате с помощью Send(Post)Message


leonidus   (2004-07-06 13:36:00) [16]

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


Reindeer Moss Eater   (2004-07-06 13:08:00) [17]

в результате потоки качают не параллельно а один за другим, т.е. сначала первый потом второй.

У тебя "качают" не поток и, а поток. Один есдинственный.
И называется он - главный поток.

Что я делаю не так?
Программируешь методом copy/paste кода чужих дурных примеров.


leonidus   (2004-07-06 08:39:00) [18]

Slym если не сложно можно пример, или просто мой код подредктируйте пожалуйста.


Slym   (2004-07-06 05:14:00) [19]

Synchronize- убери
idHTTP - лучше создавать в самом потоке, т.е. локальная переменная для потока


Наверх

Титульная страница Поиск, карта сайта Написать письмо