Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.63 MB
Время: 0.049 c
11-1197987179
nikfel
2007-12-18 17:12
2009.03.29
Как проиграть wav-файл.


2-1233922041
КирилЛ
2009-02-06 15:07
2009.03.29
Как узнать "автономер" сохраняемой записи?


15-1232751624
Четыре
2009-01-24 02:00
2009.03.29
Компонент добавляющий в заголовок окна кнопку справа Помогите


1-1209030616
psa247
2008-04-24 13:50
2009.03.29
multiselect stringgrid


15-1233223249
desc
2009-01-29 13:00
2009.03.29
Как обновить набор данных ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский