Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.003 c
15-1363564783
О-Сознание
2013-03-18 03:59
2013.08.18
Цветной TProgressBar.


15-1363336410
@!!ex
2013-03-15 12:33
2013.08.18
Ищу программиста, для разовой работы


15-1363638605
Юрий
2013-03-19 00:30
2013.08.18
С днем рождения ! 19 марта 2013 вторник


3-1292399636
tadalex
2010-12-15 10:53
2013.08.18
Латвийская кодировка


15-1363589655
Ghost del vonte
2013-03-18 10:54
2013.08.18
Что за день сегодня такой?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский