Форум: "Начинающим";
Текущий архив: 2013.08.18;
Скачать: [xml.tar.bz2];
ВнизЗагрузка страниц в Потоке с idHTTP Найти похожие ветки
← →
Pcrepair © (2012-12-11 23:03) [0]Добрый день. Есть код:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
ListBox1: TListBox;
procedure ListBox1DblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses uThreadLoader;
procedure TForm1.ListBox1DblClick(Sender: TObject);
var ThreadLdr: TLoader; HtmlCode:string;
begin
ThreadLdr:=Tloader.Create(True); (*создаем поток*)
ThreadLdr.Priority:=tpNormal; (*задать приортет нормальный*)
ThreadLdr.FreeOnTerminate:=True; (*самовыгрузка в конце потока*)
ThreadLdr.Resume; (*запускаю поток - что то устаревшее заменить?*)
ThreadLdr.Url:=ListBox1.Items[ListBox1.ItemIndex]; (*передаем УРЛ из ЛБ в Поток, все работает*)
HtmlCode:=ThreadLdr.Html; (*получаем результат ТУТ ПУСТО!!!*)
Memo1.Lines.Add(HtmlCode); (*выводим результат в МЕМО*)
end;
end.
и дополнительный модульunit uThreadLoader;
interface
uses
System.Classes, idHTTP, SysUtils, Dialogs;
type
TLoader = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
procedure LoadPage;
public
Url, Html:string;
end;
implementation
procedure Tloader.LoadPage;
var
Ldr:TidHTTP;
begin
Ldr:=TidHTTP.Create(nil);
Html:=Ldr.Get(Url);
ShowMessage(Html); (*тут страница есть*)
FreeAndNil(Ldr);
end;
procedure TLoader.Execute;
begin
Synchronize(LoadPage);
end;
end.
Задача была такая: загрузить страницу посредством idHTTP но с использованием класса TThread. Вроде все по теории?
Вопросы:
- почему не передается код страницы в HtmlCode:=ThreadLdr.Html;???? УРЛ через переменную доходит до idHTTP, а обратно нет
- РАД говорит что [dcc32 Warning] Unit1.pas(44): W1000 Symbol "Resume" is deprecated или устарело. а чем заменить?
← →
DVM © (2012-12-12 00:27) [1]
> ThreadLdr.Url:=ListBox1.Items[ListBox1.ItemIndex]; (*передаем
> УРЛ из ЛБ в Поток, все работает*)
> HtmlCode:=ThreadLdr.Html; (*получаем результат ТУТ ПУСТО!
> !!*)
вот здесь у тебя ошибка, даже 2 по одной в каждой строке.
← →
Медвежонок Пятачок © (2012-12-12 05:09) [2]procedure TLoader.Execute;
begin
Synchronize(LoadPage);
end;
Можешь сразу выбросить этот поток.
Весь полезный код у него выполняется в основном потоке.
← →
Медвежонок Пятачок © (2012-12-12 05:21) [3]HtmlCode:=ThreadLdr.Html; (*получаем результат ТУТ ПУСТО!!!*)
Потому что там уже все умерло.
И ты только чудом не получил AV. А чудо это обусловлено случайным и хаотичным набором инструкций на языке паскаль.
procedure TForm1.ListBox1DblClick(Sender: TObject);
var ThreadLdr: TLoader; HtmlCode:string;
begin
ThreadLdr:=Tloader.Create(True); (*создаем поток*)
ThreadLdr.Priority:=tpNormal; (*задать приортет нормальный*)
ThreadLdr.FreeOnTerminate:=True; (*самовыгрузка в конце потока*)
ThreadLdr.Resume; (*запускаю поток - что то устаревшее заменить?*)
ThreadLdr.Url:=ListBox1.Items[ListBox1.ItemIndex]; (*передаем УРЛ из ЛБ в Поток, все работает*)
HtmlCode:=ThreadLdr.Html; (*получаем результат ТУТ ПУСТО!!!*)
Memo1.Lines.Add(HtmlCode); (*выводим результат в МЕМО*)
end;
end.
Абсолютно эквивалентный твоему код, но только html никуда не пропадает:
/*гет, как и у тебя канает в основном потоке */
procedure TForm1.ListBox1DblClick(Sender: TObject);
var ThreadLdr: TLoader; HtmlCode:string;
begin
//ThreadLdr:=Tloader.Create(True); (*создаем поток*)
//ThreadLdr.Priority:=tpNormal; (*задать приортет нормальный*)
//ThreadLdr.FreeOnTerminate:=True; (*самовыгрузка в конце потока*)
//ThreadLdr.Resume; (*запускаю поток - что то устаревшее заменить?*)
//ThreadLdr.Url:=ListBox1.Items[ListBox1.ItemIndex]; (*передаем УРЛ из ЛБ в
Поток, все работает*)
//HtmlCode:=ThreadLdr.Html; (*получаем результат ТУТ ПУСТО!!!*)
HtmlCode := idTHHP1.Get(ListBox1.Items[ListBox1.ItemIndex]);
Memo1.Lines.Add(HtmlCode); (*выводим результат в МЕМО*)
end;
end.
← →
Pcrepair © (2012-12-12 07:52) [4]DVM
> вот здесь у тебя ошибка, даже 2 по одной в каждой строке.
а если канкретно?
ну ясно что правильно будетThreadLdr:=Tloader.Create(True); (*создаем поток*)
ThreadLdr.Priority:=tpNormal; (*задать приортет нормальный*)
ThreadLdr.FreeOnTerminate:=True; (*самовыгрузка в конце потока*)
ThreadLdr.Url:=ListBox1.Items[ListBox1.ItemIndex];
ThreadLdr.Resume;
а как правильно вернуть полученные данные?
Медвежонок Пятачок
если ты не понял - это демокод, просто наглядный пример
> Задача была такая: загрузить страницу посредством idHTTP
> но с использованием класса TThread.
а ты предлагаешь вообще поток удалить. что называется: здгавствуй ЖНГ!!
//ThreadLdr:=Tloader.Create(True); - это как понимать? тебе нравится AV?
← →
brother © (2012-12-12 08:01) [5]Ты не понимаешь как работать с потоками?
← →
Медвежонок Пятачок © (2012-12-12 08:03) [6]Все что делает твой поток:
рождается.
получает урл.
просит главный поток, что бы тот закачал этот урл
ждет когда главный закачает.
дождавшись, умирает.
больше он ничего не делает.
← →
brother © (2012-12-12 08:03) [7]читай это: http://www.delphimaster.ru/articles/panov/
обрати внимание на:Так как процедура, вызываемая в методе Synchronize выполняется в основном потоке, то на время выполнения Synchronize главная форма будет блокирована для ввода, обновления информации, как это происходит при длительных операциях в основном потоке.
Поэтому этот метод надо вызывать по возможности реже.
← →
Медвежонок Пятачок © (2012-12-12 08:15) [8]а ты предлагаешь вообще поток удалить. что называется: здгавствуй ЖНГ!!
//ThreadLdr:=Tloader.Create(True); - это как понимать? тебе нравится AV?
Никакого АВ, дурашка не будет.
Потому что не будет обращения к твоему бесполезному потоку.
Все строки связанные с ним у меня закоментированы.
а idHTTP1 положи на форму, если ты об этом.
← →
Германн © (2012-12-12 09:56) [9]
> Задача была такая: загрузить страницу посредством idHTTP
> но с использованием класса TThread. Вроде все по теории?
>
Ага. Осталось малое.
Научиться запуздыривать в Synchronize функцию, а не процедуру!
Вот только противный РАД этого не позволяет :(
← →
DVM © (2012-12-12 10:07) [10]
> Pcrepair © (12.12.12 07:52) [4]
> DVM
>
> > вот здесь у тебя ошибка, даже 2 по одной в каждой строке.
>
>
> а если канкретно?
> ну ясно что правильно будет
>
> ThreadLdr:=Tloader.Create(True); (*создаем поток*)
> ThreadLdr.Priority:=tpNormal; (*задать приортет нормальный*)
> ThreadLdr.FreeOnTerminate:=True; (*самовыгрузка в конце
> потока*)
> ThreadLdr.Url:=ListBox1.Items[ListBox1.ItemIndex];
> ThreadLdr.Resume;
>
> а как правильно вернуть полученные данные?
Да много есть способов. От Synchronize(только правильно оформленного) до сообщений. Есть и другие способы. Имхо передачу результата из вторичного потока в поток, где крутится GUI лучше всего делать с помощью сообщений (SendMessage), т.к. это самый естественный для GUI метод.
А чтобы не надо было использовать Resume, сделай конструктор с параметром и поле внутри класса потока в которое помещай значение, переданное в конструктор, а далее это же значение используй в Execute потока.
← →
Медвежонок Пятачок © (2012-12-12 10:11) [11]самое простое - убрать фрионтерминэйт.
хтмл сразу перестанет пропадать.
убить поток явно.
но страницу грузить будет все равно основной.
← →
DVM © (2012-12-12 10:20) [12]
> Pcrepair © (12.12.12 07:52)
Вообще, конечно, если твоя программа будет работать долго и грузить много-много URL, то стоит подумать над организацией пула потоков, чтоб потоки не создавать/уничтожать каждый раз (это уже не очень хорошо), а брать свободный в данный момент из пула.
Потоки, которые свою задачу выполнили, должны засыпать и просыпаться по событию, которое должно взводиться в тот момент, когда им передали очередное задание.
Ведь я так понимаю, возвращенные HTML страницы подвергаются какому то анализу, этот анализ тоже не надо делать в основном потоке. И вообще GUI - он только для визуализации процесса.
← →
Pcrepair © (2012-12-12 18:37) [13]
> Медвежонок Пятачок © (12.12.12 08:03) [6]
> Все что делает твой поток:
>
> просит главный поток, что бы тот закачал этот урл
> ждет когда главный закачает.
почему главный поток? главный поток это ведь форма. на форме обработчик который вызывает из доп. модуля поток, передает ему УРЛ и получает назад код страницы. на форме нет никаких компонентов, которые могут закачивать страницу. если не сложно, дай свой комментарий
++++++++++++++++++++++++++++++++++++++++++++
> brother © (12.12.12 08:03) [7]
> Так как процедура, вызываемая в методе Synchronize выполняется
> в основном потоке, то на время выполнения Synchronize главная
> форма будет блокирована для ввода, обновления информации,
> как это происходит при длительных операциях в основном
> потоке.
> Поэтому этот метод надо вызывать по возможности реже.
ну да, да сейчас доп. модуль такой:implementation
uses Unit1;
procedure TLoader.ShowPage;
begin
Form1.Memo1.Lines.Add(Html);
end;
procedure Tloader.LoadPage;
var
Ldr:TidHTTP;
begin
Ldr:=TidHTTP.Create(nil);
Html:=Ldr.Get(Url);
FreeAndNil(Ldr);
end;
procedure TLoader.Execute;
begin
LoadPage;
Synchronize(ShowPage);
end;
И в общем то работает, вот только uses Unit1; мне не нравится, так вроде не надо? что касается Synchronize, этот код чиста для понимания работы потока
++++++++++++++++++++++++++++++++++++++++++++++++
> DVM © (12.12.12 10:20) [12]
> Вообще, конечно, если твоя программа будет работать долго
> и грузить много-много URL, то стоит подумать над организацией
> пула потоков, чтоб потоки не создавать/уничтожать каждый
> раз (это уже не очень хорошо), а брать свободный в данный
> момент из пула.
> Потоки, которые свою задачу выполнили, должны засыпать и
> просыпаться по событию, которое должно взводиться в тот
> момент, когда им передали очередное задание.
> Ведь я так понимаю, возвращенные HTML страницы подвергаются
> какому то анализу, этот анализ тоже не надо делать в основном
> потоке. И вообще GUI - он только для визуализации процесса.
вот это наверно то что нужно, урл будет ну очень много
а примеры подобных решений кто нибуть знает?
← →
Медвежонок Пятачок © (2012-12-12 19:34) [14]....
ThreadLdr:=Tloader.Create(True); (*создаем поток*)
LogToFile("Привет, я процедура главного потока. Вот мой ThreadID: " + IntToStr(GetCurrentThreadID));
ThreadLdr.Priority:=tpNormal; (*задать приортет нормальный*)
....
procedure Tloader.LoadPage;
var
Ldr:TidHTTP;
begin
LogToFile("Привет, а я типа тоже метод вторичного потока. Но выполняюсь я вот здесь: " + IntToStr(GetCurrentThreadID));
Ldr:=TidHTTP.Create(nil);
Html:=Ldr.Get(Url);
ShowMessage(Html); (*тут страница есть*)
FreeAndNil(Ldr);
end;
procedure TLoader.Execute;
begin
LogToFile("Привет, я метод Execute вторичного потока. Вот мой ThreadID " + IntToStr(GetCurrentThreadID));
Synchronize(LoadPage);
end;
... Где LogToFile - процедура записи в текстовый файл
← →
Pcrepair © (2012-12-12 21:11) [15]Удалено модератором
← →
Медвежонок Пятачок © (2012-12-12 21:18) [16]ты просил меня прокомментировать почему лоадпейдж выполнялся в главном потоке?
я тебе прокомментировал.
← →
Pcrepair © (2012-12-12 21:22) [17]Удалено модератором
← →
Медвежонок Пятачок © (2012-12-12 21:24) [18]Удалено модератором
← →
Медвежонок Пятачок © (2012-12-12 21:29) [19]Удалено модератором
← →
Игорь Шевченко © (2012-12-12 21:32) [20]Lamers must die!
← →
имя (2012-12-12 22:36) [21]Удалено модератором
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.08.18;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.002 c