![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Добрый день.
Есть функция вида function LoadPage(const Url:string):string; для закачки страниц на базе idHHP.Get, которая обеспечивает: - закачку страниц с фреймами - закачку страниц по HTTPs - смену Request.UserAgent (доп. функция) по Random из списка агентов - подавление исключений в коде idHHP.Get с записью в лог причин - вывод сообщений о утечке памяти при закрытии Арр Сама по себе функция работает нормально, загружает все страницы и без утечки памяти. Есть код запуска этой функции в многопоточном режиме: Код:
+++++++++++++++++++++++++++++++++++++++ unit Main; .... implementation {$R *.dfm} uses uLoadPage,uGlobalVar; (*нажимает эту кнопку и понеслось*) procedure TMainForm.Btn_StartLoadURLsClick(Sender: TObject); var UrlList:TStringList; (*эквивалент передаваемого массива строк из ПМ*) i:integer; Url:string; (*строка = УРЛ из массива*) begin UrlList:=TStringList.Create; UrlList.Text:=Mm_InsSMUrls.Text; (*ввод массива строк УРЛ*) (*----ЦИКЛ мульти закачки страниц по числу УРЛ в Mm_InsSMUrls---*) for i := 0 to UrlList.Count-1 do begin Url:=UrlList[i]; (*передача УРЛ*) Loader(Url); (*вызов процедуры запуска потока закачки страницы*) Sleep(10); (*страховка от перегрева процессора а также от толпы потоков, которые мешают друг другу?*) end; FreeAndNil(UrlList); end; +++++++++++++++++++++++++++++++++++++++ unit uLoadPage; interface uses SysUtils, uThreadLoader, Classes; Procedure Loader(Url:string); implementation Procedure Loader(Url:string); var ThreadLdr: TLoader; begin ThreadLdr:=Tloader.Create(True); ThreadLdr.Priority:=tpNormal; ThreadLdr.FreeOnTerminate:=True; ThreadLdr.Url:=Url; ThreadLdr.Start; end; end. +++++++++++++++++++++++++++++++++++++++ unit uThreadLoader; interface uses System.Classes, idHTTP, SysUtils, Dialogs; type TLoader = class(TThread) private FUrl:string; FHtml:string; { Private declarations } protected procedure Execute; override; procedure CallStore; function LoadHtmlCode(const Url:string):string; public property Url: string read FUrl write FUrl; (*свойство класа, доступное для всей программы*) property Html: string read FHtml write FHtml; end; implementation uses uPageLoader, uLoadPage, uGlobalVar; function TLoader.LoadHtmlCode(const Url:string):string; begin Result:=LoadPage(Url); (*вызываем функцию загрузки страницы из uPageLoader*) end; procedure TLoader.CallStore; begin gStore.Add(Html); (*ввод новой строки в ГлобПерем*) end; procedure TLoader.Execute; begin Html:=LoadHtmlCode(Url); (*загрузка страницы в Поле Класса(свойство)*) CS.Enter; (*вход в КС*) CallStore; (*передаем результат в ГП*) Cs.Leave; (*выход из КС*) end; end. ++++++++++++++++++++++++++++++++++++++++++++ unit uPageLoader; interface uses Classes, SysUtils, idHTTP, StrUtils, IdSSL, IdSSLOpenSSL; function LoadPage(const Url:string):string; (*Основная функция Юнита*) procedure ErrorLog(Url:string); function LoadHtmlPage(const PageUrl:string):string; function DelJS(const Code:string):string; function RestoreFrame(const Code:string):string; function RestoreFullUrl(const Code:string; const RootUrl:string):string; function GetRandomUserAgent: string; var Loader:TidHTTP; SSL:TIdSSLIOHandlerSocketOpenSSL; implementation тут много чего, но все работает, смотри в начало end. ++++++++++++++++++++++++++++++++++++++++++++ unit uGlobalVar; interface uses Classes, SysUtils, SyncObjs; var gStore: TStringList=nil; (*ГП для хранения закачанных страниц*) CS:TCriticalSection; (*используем КС для передачи результата в основной поток*) implementation initialization gStore:=TStringList.Create; gStore.Duplicates:=dupAccept; gStore.Sorted:=False; Cs:=TCriticalSection.Create; finalization FreeAndNil(gStore); FreeAndNil(CS); end. ++++++++++++++++++++++++++++++++++++++++++++ В режиме отладки видно что возникает множество самых различных ошибок: - First chance exception at $00407466. Exception class $C0000005 with message 'access violation at 0x00407466: read of address 0x000000a4'. Process Loader_VER06.exe (2012) - First chance exception at $7C812AFB. Exception class EIdHTTPProtocolException with message 'Set-Cookie: dle_password=deleted; expires=Tue, 27-Dec-2011 20:37:50 GMT; path=/; domain=.freeseller.ru; httponly'. Process Loader_VER06.exe (2012) First chance exception at $00629F8C. Exception class $C0000005 with message 'access violation at 0x00629f8c: read of address 0x00000148'. Process Loader_VER06.exe (2012) - First chance exception at $7C812AFB. Exception class EOSError with message 'System Error. Code: 123. Синтаксическая ошибка в имени файла, имени папки или метке тома'. Process Loader_VER06.exe (2012) - First chance exception at $7C812AFB. Exception class EIdNotASocket with message 'Socket Error # 10038 Socket operation on non-socket.'. Process Loader_VER06.exe (2012) В рабочем режиме, за счет подавления исключений, все это конечно не вылазит, но: - закачиваются не все страницы(хотя все УРЛ валидные и функцией закачки закачиваются без вопросов) - после закрытия Арр выводится сообщение о многочисленных маленьких утечках памяти По теории потоки не должны пересекаться. каждый имеет свою память. вывод результата через КС. такое впечетление что потоки как то мешают друг другу Внимание!!! Вопрос: в чем может быть причина появления исключений и утечки памяти именно в режиме многопотоковой закачки? |
#2
|
||||
|
||||
![]() Ну кагбэ try finally надо пользовать, вполне возможно, что объекты остаются в живых при исключении.
По поводу AV вылавливай в отладчике, возможно, какой-то объект мертвый. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |