Форум: "Начинающим";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
ВнизОрганизация работы потоков Найти похожие ветки
← →
Тимоха (2009-02-02 11:34) [40]Задумывался. В моем случае ничто и никто.
← →
Медвежонок Пятачок © (2009-02-02 11:35) [41]procedure TThread_Start_First.Execute;
begin
...
syncronize(get_page);
...
syncronize(updateresults);
end;
Код твоего чудесного вторичного потока на 99% работает в контексте главного потока.
Зачем тебе вообще поток понадобился?
← →
Сергей М. © (2009-02-02 11:37) [42]
> Задумывался. В моем случае ничто и никто.
Тогда зачем нужен блок перхвата-обработки этого исключения ?
← →
Тимоха (2009-02-02 11:38) [43]Чтобы был доступ к VCL, не было тормозов, и работали сразу несколько процедур параллельно.
← →
Тимоха (2009-02-02 11:39) [44]
> Тогда зачем нужен блок перхвата-обработки этого исключения
> ?
Скопировал с примера. Забыл убрать.
← →
sniknik © (2009-02-02 11:40) [45]> но при этом никто "правильного" кода не приводит :(
вот тут ты врешь... и там главное не код, главное понять в чем к нему претензии, и самому так не делать. вот нафига тебе тут поток если вся работа идет в основном?
р.с. приведи какую нибудь ссылку с плохими отзывами... посмотрим.
> так будет вернее?
у тебя в моторе ломик застрял, из-за которого он не заводится, а ты машине фары меняешь и спрашиваешь "может так заведется?".
← →
sniknik © (2009-02-02 11:43) [46]> и работали сразу несколько процедур параллельно.
при твоем подходе они все будут стоять в очереди у главного... т.е. куча усилий и пшик в итоге.
← →
Сергей М. © (2009-02-02 11:43) [47]
> Забыл убрать
Так.
Что еще ты забыл убрать ?
← →
Медвежонок Пятачок © (2009-02-02 11:51) [48]Смело делай Shift+Del на папке проекта. А Архангельского, или откуда там ты копировал примеры - на растопку.
Потом все сначала и уже с применением мозга.
← →
Тимоха (2009-02-02 12:12) [49]Спасибо всем за ответы, очень ценю вашу помощь!
Решил попробовать по другому.
Код формы:procedure TForm1.btn1Click(Sender: TObject);
var
potok: TTest;
begin
potok := TTest.Create(true);
potok.FreeOnTerminate := true;
potok.Priority := tpLowest;
potok.Resume;
end;
код потока:uses
Classes, idhttp, unit1, StrUtils;
type
TTest = class(TThread)
private
http: tidhttp;
page: string;
{ Private declarations }
protected
procedure update;
procedure Execute; override;
end;
implementation
procedure TTest.Execute;
begin
http := TIdHTTP.Create(nil);
http.ProtocolVersion := pv1_1;
page := http.Get("http://www.delphimaster.ru/cgi-bin/forum.pl?n=18");
Synchronize(update);
http.Free;
end;
procedure TTest.update;
var
i, index, count: Integer;
s:string;
begin
count := 0;
index := PosEx("<nobr>", page, count);
repeat
count := PosEx("", page, index);
s := Copy(page, index+9, count - index - 9);
Form1.lst1.Items.Add(s);
index := PosEx("<nobr>", page, count);
until index = 0;
end;
Ругайте :)
← →
Тимоха (2009-02-02 12:15) [50]По нажатию на кнопку, создаю поток, говорю ему чтобы сам освободился, ставлю приоритет ниже vcl"кого, запускаю.
В потоке: создаю http, скачиваю страницу, использую syncronize, в котором ищу имена авторов и добавляю их на форму.
← →
Медвежонок Пятачок © (2009-02-02 12:17) [51]двойка за хардкодед урл.
за Form1.lst1.Items.Add(s); в методе потока расстрел через повешение.
← →
Сергей М. © (2009-02-02 12:21) [52]
> Тимоха
Уже ощутимо лучше.
Но:
1. А если запрашиваемый ресурс окажется недоступным ?
2. А если завтра Form1.lst1 превратятся во что-то другое или совсем исчезнут из проекта ?
← →
Медвежонок Пятачок © (2009-02-02 12:27) [53]TTest = class(TThread)
...
constructor CreateIt(const AURL : string; AList : TString); override;
end;
Только все равно это будет неправильно.
Нельзя просто взять кусок программы и вынести его в поток.
Выносить нужно со смыслом и чтобы польза была.
Этот твой поток сейчас те самые чернила для седьмого класса.
Содержат код, могущий получить любую страницу, но в методе update подразумевается что это вполне конкретная страница.
Номальные люди так код не структурируют.
← →
Тимоха (2009-02-02 12:40) [54]
> Сергей М.
А если попробовать так, создаем буфер, поток в него сохраняет данные и посылает форме сообщение, а та на сообщения добавляет содержимое буфера в листбокс?
> Медвежонок Пятачок
Не совсем понятно что оставлять в основном потоке, а что выносить в раба.
Можете привести пример?
← →
Медвежонок Пятачок © (2009-02-02 12:46) [55]Поток должен тягать урл ресурс и уметь возвращать результат вызываеющему коду и больше ничего не должен делать.
тогда он будет полезен с точки зрения повторного использования кода.
а с текущим подходом потребуется для каждого урл ресурса писать отдельные потоки, в которых дублируется один и то же код реализующий взаимодействие с веб-сервером.
Т.е. никому не нужный мартышкин труд.
Будет десять потоков-близнецов.
Однажды ты решишь перейти с инди на что-то другое или просто на другую версию инди где изменена внутренняя иерархия классов - и привет.
Засучивай рукава и модифицируй код всех десяти классов.
← →
Тимоха (2009-02-02 12:51) [56]Т.е. вы предлагаете в поток вывести только скачку страницы, а результат скачивание отдавать основному потоку и все функции и процедуры, которые парсят текст должны находится тоже в основном потоке?
← →
Медвежонок Пятачок © (2009-02-02 12:54) [57]пофик где они будут находится.
но они не должны находиться в потоке, скачивающем ресурс.
← →
Сергей М. © (2009-02-02 12:54) [58]
> Тимоха (02.02.09 12:40) [54]
А зачем потоку знать про какие-то формы и окна ?
Достаточно сказать ему, мол, на тебе первым параметром конструктора URL, делай свое дело, когда будешь готов отдать результат работы, вызови вот такой-то метод, который тебе передан, например, вторым параметром конструктора.
← →
Тимоха (2009-02-02 13:08) [59]Почему пофиг, если процедур, которые должны параллельно парсить данные будет больше 1, то форма явно будет плохо откликаться пользователю. Значит скачиванием страниц будет заниматься один поток. А другие можно направить на анализ данных. Верно?
По поводу второго параметра конструктора, про метод. Не понял как это будет выглядеть.
← →
Медвежонок Пятачок © (2009-02-02 13:11) [60]Значит скачиванием страниц будет заниматься один поток.
Да хоть сто потоков пусть занимаются скачиванием.
Я тебе говорю про то, что класс скачивающего потока должен быть один-единственный.
← →
Сергей М. © (2009-02-02 13:13) [61]
> Не понял как это будет выглядеть
Даже если не понял, то есть еще и событие TThread.OnTerminate - перед стартом потока назначь свой обработчик и в теле обработчика обращайся к объекту-потоку для считывания результатов его работы
← →
Тимоха (2009-02-02 13:48) [62]Спасибо! А что должно выступать в роли буфера, через который будут добавляться данные в мэйн тред?
← →
Медвежонок Пятачок © (2009-02-02 13:52) [63]...
private
...
page: string;
....
← →
Сергей М. © (2009-02-02 13:56) [64]
> что должно выступать в роли буфера
Например, свойства того самого объекта-потока
← →
Anatoly Podgoretsky © (2009-02-02 14:54) [65]> Тимоха (02.02.2009 11:29:36) [36]
Да ну, так и не приводят?
← →
Тимоха (2009-02-02 19:46) [66]Основной поток:
procedure TForm1.btn1Click(Sender: TObject);
var
potok: TTest;
begin
potok := TTest.Create(true);
potok.FreeOnTerminate := true;
potok.Priority := tpNormal;
potok.Main_handle := Form1.Handle;
potok.Url := "http://www.delphimaster.ru/cgi-bin/forum.pl?n=18";
potok.Resume;
end;
procedure TForm1.handlenewdata(var message: TMessage);
var
data: PChar;
begin
data := PChar(Pointer(message.LParam)^);
lst1.Items.Add(data)
end;
Рабочий поток:type
TTest = class(TThread)
private
http: tidhttp;
page: string;
FMain_handle: THandle;
FUrl: string;
{ Private declarations }
constructor create;
protected
procedure Execute; override;
public
property Url: string write FUrl;
property Main_handle: THandle write FMain_handle;
end;
implementation
constructor TTest.Create;
begin
inherited Create(True);
FreeOnTerminate := True;
Self.Priority := tpNormal;
Resume;
end;
procedure TTest.Execute;
var
index, count: Integer;
s: PAnsiChar;
begin
http := TIdHTTP.Create(nil);
http.ProtocolVersion := pv1_1;
page := http.Get(FUrl);
count := 0;
index := PosEx("<nobr>", page, count);
repeat
count := PosEx("", page, index);
GetMem(s, SizeOf(s));
s := PChar(Copy(page, index + 9, count - index - 9));
SendMessage(FMain_handle, wm_buf, 0, dword(@s));
index := PosEx("<nobr>", page, count);
until index = 0;
http.Free;
end;
так нормально?
← →
Palladin © (2009-02-02 19:54) [67]бред. перепродумай. посмотри на конструктор потока (код конструктора выполняется в основном потоке), и посмотри что у тебя творится в btn1click. почувствуй бред )
← →
Тимоха (2009-02-02 20:41) [68]
constructor Create(h: THandle; Url: string); overload;
constructor TTest.Create(h: THandle; Url: string);
begin
inherited Create(True);
FUrl := url;
hwnd := h;
Self.Priority := tpNormal;
Self.FreeOnTerminate := true;
http := TIdHTTP.Create(nil);
Resume; имеет разницу где выполнять поток, здесь или в мэйнтреде
end;
procedure TForm1.btn1Click(Sender: TObject);
var
potok: TTest;
begin
potok := TTest.create(form1.Handle, "http://www.delphimaster.ru/cgi-bin/forum.pl?n=18");
end;
← →
Anatoly Podgoretsky © (2009-02-02 21:29) [69]> Тимоха (02.02.2009 20:41:08) [68]
А у тебя где выполняется
← →
Тимоха (2009-02-02 21:30) [70]сейчас в create потока.
← →
Сергей М. © (2009-02-02 21:55) [71]
> Тимоха (02.02.09 20:41) [68]
> Self.Priority := tpNormal;
> Self.FreeOnTerminate := true;
Опять "забыл" ?
теперь-то откуда скопировал ?)
← →
Anatoly Podgoretsky © (2009-02-02 23:18) [72]> Тимоха (02.02.2009 21:30:10) [70]
create выполняется в основном потоке.
← →
Тимоха (2009-02-02 23:37) [73]Когда тогда надо задавать приоритет? и выставлять freeonterminate?
← →
Eraser © (2009-02-02 23:44) [74]> [73] Тимоха (02.02.09 23:37)
> Когда тогда надо задавать приоритет?
в начале OnExecute.
> и выставлять freeonterminate?
где угодно, можно там же.
← →
Тимоха (2009-02-02 23:48) [75]если я правильно понял:
procedure TTest.Execute;
begin
Self.Priority := tpNormal;
Self.FreeOnTerminate := true;
...
end;
Но почему именно так?
← →
Eraser © (2009-02-02 23:52) [76]> [75] Тимоха (02.02.09 23:48)
можно и не так, можно и из вне, так понятнее.
← →
Тимоха (2009-02-03 00:01) [77]мне не понятно почему неправильно держать эти строки в конструкторе потока?
← →
Eraser © (2009-02-03 00:22) [78]> [77] Тимоха (03.02.09 00:01)
можно, только после inherited.
← →
Riply © (2009-02-03 00:51) [79]> [73] Тимоха (02.02.09 23:37)
> Когда тогда надо задавать приоритет? и выставлять freeonterminate?
Да мне кажется, что Сергей М. в [71] инересовался присхождением Self. :)
P.S.
А ты молодец.
При прочтении данной ветки, складывается такое впечатление, что все у тебя получится.
(Рано или поздно :) )
← →
Тимоха (2009-02-03 00:58) [80]Спасибо! что плохого в Self?
Страницы: 1 2 3 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
Память: 0.62 MB
Время: 0.066 c