Показать сообщение отдельно
  #2  
Старый 12.12.2012, 08:00
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Pcrepair
Есть код:
Код:
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;
Во-первых порядок действий такой: сначала создаёшь объект потока остановленным, настраиваешь ему нужные параметры и потом запускаешь его на выполнение с помощью Resume. Т.е после того как поток запущен - уже поздно его "донастраивать" (речь идёт о присвоении Url после Resume).
Во-вторых почему ты сразу пытаешься прочитать из объекта потока значение поля Html? После Resume дополнительный поток живёт своей жизнью, а главный поток своей. Почему ты думаешь, что когда в главном потоке дело дойдёт до строки "HtmlCode:=ThreadLdr.Html" то дополнительный поток уже успеет скачать страницу?
В-третьих зачем ты вообще пытаешь в главном потоке прочитать у объекта потока значение поля Html? Возможно что когда в главном потоке дело дойдёт до строки "HtmlCode:=ThreadLdr.Html" то дополнительный поток уже успеет и скачать страницу и разрушить свой объект (у тебя он саморазрушаемый: FreeOnTerminate:=True) и поэтому переменная ThreadLdr будет указывать в никуда (точнее она будет указывать на то место, где раньше был объект, а теперь "руины" от него, при обращении к которым в программе может случиться "авария" типа Access Violation). Другими словами так как страницу качает дополнительный поток, то значит именно он знает когда страница закачалась, а значит именно ему решать кода уже можно "публиковать" эту страницу в Memo1 (или куда-то там ещё), а вовсе не главному потоку.
Цитата:
Сообщение от Pcrepair
Код:
procedure TLoader.Execute;
begin
   Synchronize(LoadPage);
end;
И какой был смысл создавать дополнительный поток? Метод Synchronize приостанавливает дополнительный поток и выполняет метод LoadPage в главном потоке, а значит качать будет опять главный поток. С тем же успехом можно было не создавая никаких потоков просто качать в обработчике ListBox1DblClick.
Ответить с цитированием