![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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 - лучше создавать в самом потоке, т.е. локальная переменная для потока