Форум: "Сети";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
ВнизTidHTTP при работе в потоке Найти похожие ветки
← →
leonidus (2004-07-05 22:45) [0]Есть код:
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?
← →
Slym © (2004-07-06 05:14) [1]Synchronize- убери
idHTTP - лучше создавать в самом потоке, т.е. локальная переменная для потока
← →
leonidus (2004-07-06 08:39) [2]Slym если не сложно можно пример, или просто мой код подредктируйте пожалуйста.
← →
Reindeer Moss Eater © (2004-07-06 13:08) [3]в результате потоки качают не параллельно а один за другим, т.е. сначала первый потом второй.
У тебя "качают" не потоки, а поток. Один есдинственный.
И называется он - главный поток.
Что я делаю не так?
Программируешь методом copy/paste кода чужих дурных примеров.
← →
leonidus (2004-07-06 13:36) [4]Я понял, что приложение работает не как многопоточное а как однопоточное, как грамотно исправитьмой код что бы программа работала в два потока.
← →
Reindeer Moss Eater © (2004-07-06 13:47) [5]Synchronize- убери
URL передавай конструктору потока (или как - нибудь иначе)
После успешной закачки извещай основной поток о результате с помощью Send(Post)Message
← →
Digitman © (2004-07-06 13:58) [6]
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");
← →
leonidus (2004-07-06 15:47) [7]>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?
← →
Reindeer Moss Eater © (2004-07-06 16:09) [8]1. Никакой. Terminate не убивает потоки
2. Все исключения в потоке должны быть обработаны в потоке
← →
Reindeer Moss Eater © (2004-07-06 16:11) [9]TMyThread.Terminate
Тем более, что так писать безграмотно.
Terminate это метод, а не классовый метод.
Вызывать его надо у конкретного экземпляра, а не у класса
← →
Reindeer Moss Eater © (2004-07-06 16:16) [10]Ну и вообще зачем вызывать Terminate, если:
constructor TMyThread.Create(Host: String; Port: Integer; URL, FileName: String);
begin
...
FreeOnTerminate := True;
...
end;
"Для мебели"?
Зря все же тебе дали готовый пример. Не в прок.
← →
Digitman © (2004-07-06 16:39) [11]
> leonidus (06.07.04 15:47) [7]
> Я правильно понял, что операторы..
> выполнятся сразу один за другим и запустят два потока?
правильно
1. Никакой. см.[8],[9]
Вопрос про принудительное "убийство" ты не ставил изначально, поэтому в примере поток корректно "умирает" сам, при успешном выполнении - молча, при ошибке - выведя перед этим диалог с причиной ошибки
Про потоковый "суицид" читай справку о св-ве FreeOnTerminate
2. Обрати внимание на try..except в теле Execute() - ЛЮБЫЕ исключительные ситуации перехватываются и обрабатываются простейшим образом, освобождение же ресурсов безусловно осуществляется во вложенном блоке try..finally
вообще-то говоря, пример приведен для детального анализа его простейшего алгоритма, а не для подобных вопросов.. на то и пример
← →
leonidus (2004-07-07 07:55) [12]Спасибо всем, в особенности Digitman.
>Reindeer Moss Eater хочу вам сказать, что если вы хороший программист, то это не заначит, что надо унижать тех кто в этом деле не так силен, тем более что иногда приходится заниматься программированием не только программистам, но и обыным технарям.
← →
Digitman © (2004-07-07 08:10) [13]
> leonidus (07.07.04 07:55) [12]
напрасно ты считаешь себя "униженным"..
RME прав по сути, даже если имел неосторожность высказаться в резком тоне ..
ну посуди сам - ведь код приведен для детального построчного анализа, со справочным материалом в руках, а твои вопросы в [7] говорят о том, что прежде чем их задавать ты даже не вник в этот код
← →
leonidus (2004-07-07 15:17) [14]Я не спорю, у меня просто не хватает базовых знаний, а в книжках не всегда понятно пишут, я так понимаю что форумы для того и существуют что бы задавать вопросы...
← →
Reindeer Moss Eater © (2004-07-07 15:34) [15]так понимаю что форумы для того и существуют что бы задавать вопросы...
Тебе их кто-то запрещал задавать?
Нет.
Тебе не нравятся ответы? А думаешь вопросы твои очень симпатичные?
← →
leonidus (2004-07-08 15:12) [16]Если бы я умел задавать симпатичные вопросы, то наверное сам бы смог на них ответить, а пока вопросы соответсвуют степени моего понимания данной проблемы
← →
Digitman © (2004-07-08 15:26) [17]
> степени моего понимания данной проблемы
степень твоего понимания данной и последующих проблем, поверь уж, находится и будет находиться от желания и умения анализировать код и самостоятельно работать со справочным материалом
← →
Reindeer Moss Eater © (2004-07-08 15:26) [18]Так вот.
До тех пор пока ты не начал предъявлять претензии к качеству ответов, никто тебе не ставил в вину качество твоих вопросов.
На них просто отвечали и все.
← →
Digitman © (2004-07-08 15:39) [19]
> leonidus
и еще.
никто не спорит, что справочный материал (по классам и компонентам от Борланда в дан.случае) весьма скуден и порой не дает однозначных ответов на конкретные вопросы
Но ! Есть ведь исх.тексты этих классов .. и опять все сводится к необходимости анализировать эти тексты, дабы познать непознанное, коль есть желание и целеустремленность
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.065 c