Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.03.29;
Скачать: CL | DM;

Вниз

Организация работы потоков   Найти похожие ветки 

 
Тимоха   (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;
Скачать: CL | DM;

Наверх




Память: 0.63 MB
Время: 0.026 c
2-1234257405
Scot Storch
2009-02-10 12:16
2009.03.29
службы (сервисы)


15-1232703880
123-ий
2009-01-23 12:44
2009.03.29
Шестисотая БМВ


1-1208160317
@!!ex
2008-04-14 12:05
2009.03.29
Проверка корректности файла


15-1232270164
palva
2009-01-18 12:16
2009.03.29
Все верующие купаются сегодня в проруби


2-1233895829
des
2009-02-06 07:50
2009.03.29
Как отловить ошибку 405?