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

Вниз

Проблемы с потоками при закачке страниц   Найти похожие ветки 

 
Pcrepair ©   (2012-12-28 19:22) [40]

а если вот так:

type
 TLoader = class(TThread) (*создаем свой класс на базе ПОТОК*)
 private
    FUrl:string; (*поле класса типа СТРОКА для чтения -записи данных*)
    FIdHttp:TidHTTP;
    FSSL:TIdSSLIOHandlerSocketOpenSSL;
 protected
   procedure Execute; override;
   function LoadHtmlCode(const Url: String):string; (*ФУНК загрузки страницы*)
 public
   property Url: string read FUrl write FUrl;  (*свойство класа, доступное для всей программы*)
   constructor Create;
   destructor Destroy; override;
 end;

implementation
uses Unit1, uLoadPage, uGlobalVar;

constructor TLoader.Create;
begin
 inherited Create(True); (*Поток создаем в состоянии «Приостановлен»*)
 FIdHttp := TIdHTTP.Create(nil);
 FSSL := TIdSSLIOHandlerSocketOpenSSL.Create;
 FreeOnTerminate := True; (* Поток освободит ресурсы при окончании работы*)
 Self.Priority := tpNormal;
end;

destructor TLoader.Destroy;
begin
 FreeAndNil(FIdHttp);
 FreeAndNil(FSSl);
end;

(*  28.12.2012 функция загрузки страницы прямо в коде потока*)
function TLoader.LoadHtmlCode(const Url: String):string;
begin
 FIdHttp.IOHandler:=FSSL;
 FIdHttp.HandleRedirects:=True;
 Result:=FIdHttp.Get(Url);
end;

procedure TLoader.Execute;
var Code:string;
begin
   Code:=LoadHtmlCode(Url);
     begin
      CS.Enter;  (*вход в КС*)
        try
          gStore.Add(Code); (*передаем результат в ГП*)
        finally
     Cs.Leave;  (*выход из КС*)
    end;
 end;
end;

end.

то есть функция загрузки с idHTTP прямо в потоке. потом тут же дописать обертку (небольшой цикл по закачке фреймов) а функции обработки кода страницы вообще вызывать в поток из другого модуля
или еще лучще тут их написать но не как метод потока а сверху так сказать. или все же лучше сделать все функции методами класса??


 
Сергей М. ©   (2012-12-28 20:05) [41]


> constructor TLoader.Create;
> ..
>  Self.Priority := tpNormal; // эта строчка гуляет по Тырнету в миллионах экз-рах, ты ее позорно сдул  - и какое отношение к себе при этом ты изволишь желать ?
>..
> end;


 
Pcrepair ©   (2012-12-28 21:02) [42]

Удалено модератором


 
Pcrepair ©   (2012-12-28 21:45) [43]

Удалено модератором
Примечание: Правила форума надо уважать


 
Германн ©   (2012-12-29 02:30) [44]

Удалено модератором


 
Pcrepair ©   (2012-12-29 20:56) [45]

ну что все уже празднуют? вопросы еще остались

сделал все функции и процедуры методами класса, из доп модулей ничего не вызывается
ошибки остались, только для этих страниц:
----------------это все из отладчика----------------------------------------
IdHTTP.TIdCustomHTTP.Get("http://www.xard.ru/post/10305/",(...))
IdHTTP.TIdCustomHTTP.Get("http://www.electrosad.ru/Electronics/PP.htm",$16D3A00,(...))
uThreadLoader.TLoader.LoadHtmlCode("http://www.xard.ru/post/10305/")

для всех пишет одно и то же(в режиме отладки):
First chance exception at $7C812AFB. Exception class EConvertError with message """"" is not a valid integer value". Process Project.exe (2728)
Что это непонятно, так как страницы закачиваются

в остальном все хорошо, утечки памяти нет, закачиваются все страницы


 
Медвежонок Пятачок ©   (2012-12-29 21:11) [46]

Что что. Это твоя обработка текста страницы. К загрузке отношения не имеющая.


 
Pcrepair ©   (2012-12-29 21:18) [47]

нет в IdHTTP.TIdCustomHTTP.Get никакой обработки.


 
Медвежонок Пятачок ©   (2012-12-29 21:23) [48]

А кто тогда делает  strtoint? Дедушко мороз?


 
Медвежонок Пятачок ©   (2012-12-29 21:30) [49]

А кто тогда делает  strtoint? Дедушко мороз?


 
Pcrepair ©   (2012-12-29 22:30) [50]

это ты так очень иносказательно, почти как дедушко Крылов, намекаешь что исключение связано с использованием системной функции?

кстати, нет там нигде StrToInt. и IntToStr то же нет


 
Медвежонок Пятачок ©   (2012-12-29 22:36) [51]

ну значит и эксепшена нет. Наверное тебе привиделось.


 
Сергей М. ©   (2012-12-29 22:41) [52]


> Что это непонятно


Это практически наверняка результат по-прежнему отсутствующей синхронизации обращения твоей дивизии потоков к какому-то общему ресурсу.


 
Pcrepair ©   (2012-12-29 22:52) [53]

да уже второй день как есть синхронизация, всего к всему
это фигня вылезает на 2-х страницах, всегда одних и тех же, из 200 в списке

кстати, повторюсь, страницы все равно закачиваются, те самые на кторых выскакивает исключение (в режиме отладки только)


 
Сергей М. ©   (2012-12-29 22:59) [54]

Если однопоточная загрузка (о чем тебе еще в [4] намекнул Вася) этих страниц не вызывает исключения, можешь смело забить на него.
В противном случае ССЗБ.


 
Игорь Шевченко ©   (2012-12-29 23:12) [55]

Pcrepair ©   (29.12.12 20:56) [45]

> для всех пишет одно и то же(в режиме отладки):
> First chance exception at $7C812AFB. Exception class EConvertError
> with message """"" is not a valid integer value". Process
> Project.exe (2728)
> Что это непонятно


Наверное в режиме отладки и строки, на которых проиходит исключение, показываются.

Не томи.


 
DVM ©   (2012-12-29 23:26) [56]


> Pcrepair ©   (28.12.12 19:22) [40]


>  public
>    property Url: string read FUrl write FUrl;  (*свойство
> класа, доступное для всей программы*)

это свойство не потокобезопасно, к нему есть обращения одновременно на изменение и чтение из разных потоков?


 
DVM ©   (2012-12-29 23:28) [57]


> Pcrepair ©   (29.12.12 22:52) [53]
> да уже второй день как есть синхронизация, всего к всему

Да ладно, не верю. Более чем уверен, что вот к этому твоему gStore есть не защищенные обращения.


 
Pcrepair ©   (2012-12-30 22:21) [58]

Игорь Шевченко

> Наверное в режиме отладки и строки, на которых проиходит
> исключение, показываются.

SysUtils

procedure ConvertErrorFmt(ResString: PResStringRec; const Args: array of const); local;
begin
 raise EConvertError.CreateResFmt(ResString, Args); (*тут*)
end;


Call stack -THread 4064

:7c812afb kernel32.RaiseException + 0x52
System.SysUtils.ConvertErrorFmt($4129A8,(...))
System.SysUtils.StrToInt("")
IdGlobal.IndyStrToInt("")
IdGlobalProtocols.RawStrInternetToDateTime("",0)
IdGlobalProtocols.GMTToLocalDateTime("")
IdHTTPHeaderInfo.TIdEntityHeaderInfo.ProcessHeaders
IdHTTPHeaderInfo.TIdResponseHeaderInfo.ProcessHeaders
IdHTTP.TIdHTTPProtocol.RetrieveHeaders(???)
IdHTTP.TIdCustomHTTP.DoRequest(???,"http://www.xard.ru/post/10305/",nil,$16D3B20,(...))
IdHTTP.TIdCustomHTTP.Get("http://www.xard.ru/post/10305/",$16D3B20,(...))
IdHTTP.TIdCustomHTTP.Get("http://www.xard.ru/post/10305/",(...))
IdHTTP.TIdCustomHTTP.Get("http://www.xard.ru/post/10305/")
uThreadLoader.TLoader.LoadHtmlCode("http://www.xard.ru/post/10305/")
uThreadLoader.TLoader.LoadPage("http://www.xard.ru/post/10305/")
uThreadLoader.TLoader.Execute
System.Classes.ThreadProc($16FE0A0)
System.ThreadWrapper($16E13E0)
:7c80b729 ; C:\WINDOWS\system32\kernel32.dll

причем на каждом УРЛ исключение выскакивает дважды
++++++++++++++++++++++++++++++++++++++++++++++++++

> это свойство не потокобезопасно, к нему есть обращения одновременно
> на изменение и чтение из разных потоков?

вообще то через это свойство в поток передается УРЛ, как оно не может быть public? потом значение из этого поля идет в поток и тд...
в конвейре запуска потоков, каждому потоку передается свое значение, после чего поток его обрабатывает. это все
---------------
к gStore любые обращения идут через CS, это не сложно


 
DVM ©   (2012-12-30 22:36) [59]


> Pcrepair ©   (30.12.12 22:21) [58]


> вообще то через это свойство в поток передается УРЛ, как
> оно не может быть public?

А кто говорил, что оно не может быть паблик? На здоровье пусть будет паблик, но оно не потокобезопасно. Сделать потокобезопасное свойство не проблема если что.


> к gStore любые обращения идут через CS, это не сложно

Ну как сказать, везде ли у тебя при любом обращении к любому свойству, любому методу этого gStore сначала происходит вход в крит секцию а потом выход? Это не всегда очевидно.


 
Pcrepair ©   (2012-12-30 22:40) [60]

и вот еще что, это исключение есть даже при самом простом коде закачки. один к одному. без всяких потоков. без gStore. без всего

unit uPageLoader;
interface
uses idHTTP, SysUtils;
 function LoadPage(const Url:string):string;
 var idHttp:TidHTTP;
implementation

function LoadPage(const Url:string):string;
begin
 idHttp:=TidHttp.Create(nil);
    Result:=idHttp.Get(Url);
 FreeAndNil(idHttp);
end;
end.


похоже это косяк ИНДИ


 
bems ©   (2012-12-30 22:42) [61]

ну похоже что по этим адресам в хидерах где-то позвращается пустая дата.
посмотри попадает ли этот эксцепшн в твой обработчик. если нет, то это внутренние дела indy

в версии индейцев которая идет с дельфи XE2 я вижу что в случае эксцепшна в RawStrInternetToDateTime она просто возвращает false и считает жксцепшн обработанным. Правда в ней же в самом начала стоит проверка не передана ли в RawStrInternetToDateTime пустая строка, и в этом случае возвращается false без возникновения эксцепшна. но может оказаться что эту проверку добавили позже и в твоей версии ее еще нет.

в общем если индейцы сами обрабатывают это исключение то беспокоиться не нужно


 
DVM ©   (2012-12-30 22:46) [62]


> Pcrepair ©   (30.12.12 22:40) [60]


> вот еще что, это исключение есть даже при самом простом
> коде закачки. один к одному.

ну возникает исключение и что? не вижу повода для паники. У тебя этих исключений может возникнуть вагон и маленькая тележка, начиная от недоступности сайта, заканчивая некорректными HTTP заголовками и пр, на что инди вполне закономерно выбрасывает исключения. Если какие то типы исключений нельзя пропускать наружу, try...except тебе в помощь, желательно с логгированием.


 
DVM ©   (2012-12-30 22:46) [63]


> Pcrepair ©   (30.12.12 22:40) [60]


> вот еще что, это исключение есть даже при самом простом
> коде закачки. один к одному.

ну возникает исключение и что? не вижу повода для паники. У тебя этих исключений может возникнуть вагон и маленькая тележка, начиная от недоступности сайта, заканчивая некорректными HTTP заголовками и пр, на что инди вполне закономерно выбрасывает исключения. Если какие то типы исключений нельзя пропускать наружу, try...except тебе в помощь, желательно с логгированием.


 
Pcrepair ©   (2012-12-30 22:51) [64]


> посмотри попадает ли этот эксцепшн в твой обработчик. если
> нет, то это внутренние дела indy

что бы это значило? это исключение видно только в режиме отладки, если запустить откомп. приложение то никаких сообщений не появляется,  все работает как предначертано

в ХЕ2 ИНДИ был очень кривой, из за его косяков при загрузке страниц пробовал даже перейти на другие варианты(ICS и прочее)
сейчас пробую ХЕ3 инди 10.5.9.0 - значительно лучше, выбор кодировки даже почти работает (80% случаев). 302 и 301 тоже работают, но видимо до ума еще доводить и доводить


 
Pcrepair ©   (2012-12-30 22:55) [65]

DVM

> Сделать потокобезопасное свойство не проблема если что.

расскажи лучше об этом поподробнее.
сейчас так:

type
 TLoader = class(TThread) (*создаем свой класс на базе ПОТОК*)
 private
    FUrl:string; (*поле класса типа СТРОКА для чтения -записи данных*)
    FIdHttp:TidHTTP;
    FSSL:TIdSSLIOHandlerSocketOpenSSL;
 protected
   procedure Execute; override;
   function LoadHtmlCode(const PageUrl: String):string; (*ФУНК загрузки страницы*)
   procedure ErrorLog(Url:string);
   function GetRandomUserAgent: string;
   function LoadPage(const Url:string):string;
   function DelJS(const Code:string):string;
   function RestoreFrame(const Code:string):string;
   function RestoreFullUrl(const Code:string; const RootUrl:string):string;
   function CorrectUrl(const UrlStr:string):string;
 public
   property Url: string read FUrl write FUrl;  (*свойство класа, доступное для всей программы*)
   constructor Create;
   destructor Destroy; override;
 end;

а раньше вообще

public
   var Url: string;  (*свойство класа, доступное для всей программы*)
   constructor Create;
   destructor Destroy; override;
 end;

и вроде все работало
твой вариант:


 
bems ©   (2012-12-30 22:56) [66]


> что бы это значило?

что indy обрабатывает это исключение, значит не косяк (хотя могли бы и без эксцепшна проверить).
ну или ты его сам глушишь, проверь что это не так


 
DVM ©   (2012-12-30 22:57) [67]


> Pcrepair ©   (30.12.12 22:51) [64]


> в ХЕ2 ИНДИ был очень кривой, из за его косяков при загрузке
> страниц пробовал даже перейти на другие варианты(ICS и прочее)

Ну и что же не перешел? Ты извини, но твоя квалификация недостаточна, для объективной оценки качества работы Indy. Indy библиотека, до которой многим другим еще расти и расти.


> выбор кодировки даже почти работает (80% случаев).

какое отношение TIdHTTP имеет к каким либо кодировкам? Это вообще не его дело.


> 302 и 301 тоже работают, но видимо до ума еще доводить и
> доводить

Нет там никаких проблем, и не было, по крайней мере у меня.


 
DVM ©   (2012-12-30 23:07) [68]


> Pcrepair ©   (30.12.12 22:55) [65]
> DVM
>
> > Сделать потокобезопасное свойство не проблема если что.
>
>
> расскажи лучше об этом поподробнее.

TMyClass = class
private
 FCS: TCriticalSection;
 FMyProp: string;
 function GetMyProp: string;
 procedure SetMyProp(const AValue: string);
public
 property MyProp: string read GetMyProp write SetMyProp;
 ..

function TMyClass.GetMyProp: string;
begin
 FCS.Enter;
 try
   Result := FMyProp;
 finally
   FCS.Leave;
 end;
end;

function TMyClass.SetMyProp(const AValue: string);
begin
 FCS.Enter;
 try
   FMyProp := AValue;
 finally
   FCS.Leave;
 end;
end;


И ГЛАВНОЕ!!! Во всех методах самого TMyClass обращаться исключительно к MyProp, но не FMyProp!!!


 
DVM ©   (2012-12-30 23:08) [69]


> Pcrepair ©   (30.12.12 22:55) [65]

и еще, описанный мной способ не прокатит для сложных свойств, представляющих собой классы и т.д., в них должны быть свои потокозащищенные поля.


 
bems ©   (2012-12-30 23:19) [70]

поковырялся
по адресу "http://www.electrosad.ru/Electronics/PP.htm" (или какому-то куда он редиректит) в заголовке "Expires" возвращается "24.02.2012"
Инди ожидают увидеть в этой строкен в качестве разделителя даты либо "-" (и называют это поддержкой бажных серверов) либо пробел. Точку там они не ожидают, поэтому у них возникает эксцепшн. В качестве обработки они считают что указана дата 30.12.1899.
Наружу, как и ожидалось, этот эксцепшн не попадает


 
Pcrepair ©   (2012-12-30 23:22) [71]

может тогда уже использовать TMultiReadExclusiveWriteSynchronizer? чем писать свои реализации чтение-запись?
----------------------------
может ИНДИ(из комплекта ХЕ2) и огого, но вот спотыкалась при загрузке некоторых страниц, причем так спотыкалась что даже полное подавление исключений не помогло - программа(простейший код) просто зависала и все. а в РАД2010 и ХЕ3 тот же самый код работает нормально.
что касается кодовой страницы: в РАД2010 - кракозябры, в ХЕ3 - кырилица в норме( в 80%) случаев. так что выводы сделать можно и без огромного опыта


 
DVM ©   (2012-12-30 23:23) [72]


> bems ©   (30.12.12 23:19) [70]


> в заголовке "Expires" возвращается "24.02.2012"

Так вроде не по стандарту же. Должно быть типа
Expires: Tue, 31 Jan 2012 15:02:53 GMT
возмущение Indy резонно.


 
DVM ©   (2012-12-30 23:25) [73]


> Pcrepair ©   (30.12.12 23:22) [71]
> может тогда уже использовать TMultiReadExclusiveWriteSynchronizer?
>  чем писать свои реализации чтение-запись?

с TMultiReadExclusiveWriteSynchronizer придется писать ровно то же что и с крит секцией.


 
DVM ©   (2012-12-30 23:30) [74]


> Pcrepair ©   (30.12.12 23:22) [71]


> может ИНДИ(из комплекта ХЕ2) и огого, но вот спотыкалась
> при загрузке некоторых страниц, причем так спотыкалась что
> даже полное подавление исключений не помогло - программа(простейший
> код) просто зависала и все. а в РАД2010 и ХЕ3 тот же самый
> код работает нормально.

И что там в исключениях написано было?


> что касается кодовой страницы: в РАД2010 - кракозябры, в
> ХЕ3 - кырилица в норме( в 80%) случаев. так что выводы сделать
> можно и без огромного опыта

Еще раз повторю, TIdHTTP не имеет никакого отношения к кодировкам. То, что у метода Get есть вариант возвращающий строку, это еще не значит что он обязан за тебя делать перекодировку. И вообще, надо использовать вариант с Get где TStream в параметрах, получать кодировку документа и перекодировать полученные данные.


 
bems ©   (2012-12-30 23:30) [75]


> Так вроде не по стандарту же.

я ж как чукча, что вижу о том и пою. И не говорю что это должно корректно обрабатываться


> возмущение Indy резонно.

они даже и не возмущаются, просто присваивают дате нулевое значение. но могли бы вместо кидания-обработки исключения и TryStrToInt делать


 
Pcrepair ©   (2012-12-30 23:37) [76]

а исключений не было. программа просто зависала и все. что в режиме отладки что откомпилилированная.

и еще раз повторю: похоже инди 10.5.9.0 УЖЕ имеет отношение к выбору кодировки страницы - видимо встроили. вот если использовать Tmemory.Stream для вывода кода закачанной страницы(idHttp>Get(Url, Stream), там действительно кракозябры вместо кырилицы, поскольку поток выводит код в первозданном виде. а если idHttp.Get(Url), кырилицы в норме(имеется ввиду закачка одной и той же страницы). у меня во всяком случае так. специально проверял


 
DVM ©   (2012-12-30 23:41) [77]


> Pcrepair ©   (30.12.12 23:37) [76]


> вот если использовать Tmemory.Stream для вывода кода закачанной
> страницы(idHttp>Get(Url, Stream), там действительно кракозябры
> вместо кырилицы, поскольку поток выводит код в первозданном
> виде

Вот именно, что в первозданном, если эту страницу надо сохранить где то, то ее в этом первозданном виде и надо сохранять, а до кучи и хидеры HTTP к ней. А перед использованием приводить к читабельному виду с помощью TStringStream с указанием кодировки например. По крайней мере так ничего не теряется от оригинала.


 
DVM ©   (2012-12-30 23:41) [78]


> Pcrepair ©   (30.12.12 23:37) [76]


> вот если использовать Tmemory.Stream для вывода кода закачанной
> страницы(idHttp>Get(Url, Stream), там действительно кракозябры
> вместо кырилицы, поскольку поток выводит код в первозданном
> виде

Вот именно, что в первозданном, если эту страницу надо сохранить где то, то ее в этом первозданном виде и надо сохранять, а до кучи и хидеры HTTP к ней. А перед использованием приводить к читабельному виду с помощью TStringStream с указанием кодировки например. По крайней мере так ничего не теряется от оригинала.


 
Pcrepair ©   (2012-12-30 23:48) [79]

и какую же кодировку указать? ту что в заголовке страницы, или ту что получена от сервера? оне часто не совпадают


 
DVM ©   (2012-12-30 23:55) [80]


> Pcrepair ©   (30.12.12 23:48) [79]


> и какую же кодировку указать?


> оне часто не совпадают

Более того они обе могут быть и неправильными. А ты от Indy хочешь чтоб она правильно перекодировала.

Вообще сначала надо смотреть кодировку страницы и если она не указана то брать кодировку сервера



Страницы: 1 2 3 вся ветка

Текущий архив: 2013.09.15;
Скачать: CL | DM;

Наверх




Память: 0.66 MB
Время: 0.01 c
3-1292492845
RWolf
2010-12-16 12:47
2013.09.15
ClientDataSet: Insufficient memory for this operation


2-1356611380
tomkat
2012-12-27 16:29
2013.09.15
CharSet TStringList


2-1356651162
NS
2012-12-28 03:32
2013.09.15
Альфа канал иконки


15-1365423706
ВВВ
2013-04-08 16:21
2013.09.15
Syntax Check - Hotkey.


2-1356513986
Tvanges
2012-12-26 13:26
2013.09.15
Сливание pdf