Текущий архив: 2005.03.20;
Скачать: CL | DM;
Вниз
Предотвращение зависания программы Найти похожие ветки
← →
leonidus (2005-02-28 08:19) [0]Ситуация следующая, в программе скачиваю последовательно несколько HTML-документов, и сразу после закачки передаю управление парсеру, который в процессе своей работы на некоторое время загружает процессор на 100%, видимо за счет выполнения конструкции:
var
HTML: TStream;
begin
if HTML.Size>0 then
begin
HTML.Seek(0,soFromBeginning);
repeat
HTML.Read(Z,1); <- шагаем по HTML-документу посимвольно
...
...
until HTML.Size<=HTML.Position;
end;
в результате пока идет цикл перебора символов HTML-документа, программа подвисает, не отвечая на внешние действия. В обычном случае я бы использовал application.ProcessMessages, но как быть тут, исходники парсера у меня есть (это сторонний компонент), но как их модифицировать что бы программа не так сильно подвисала?
← →
КаПиБаРа © (2005-02-28 08:21) [1]Идеально было бы запускать его в отдельном потоке.
← →
leonidus (2005-03-01 11:22) [2]пробовал но нвсе равно не удается, хотя я не силен в потоках. Можно примерчик?
← →
sniknik © (2005-03-01 11:25) [3]примеров валом, даже здесь
http://www.delphimaster.ru/cgi-bin/forum.pl?n=0&search=TThread
← →
leonidus (2005-03-01 11:30) [4]Описываю:
TThread1= class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
path:string; //путь к HTML-документу который нужно распарсить
end;
Запускаю
t1 := TThread1.Create(true);
t1.path:=pathHTML;
t1.resume;
Вызов парсера помещаю сюда
procedure TThread1.Execute;
var
MS1: TMemoryStream;
begin
MS1:=TMemoryStream.Create;
MS1.LoadFromFile(t1.path);
Parser1.Parse(MS1);
MS1.Free;
end;
и результата ноль. Помогите пожалуйста!
← →
leonidus (2005-03-01 12:41) [5]Может я Synchronize не исползовал поэтому поточность не работает? Но куда его поставить ума не приложу
← →
Anatoly Podgoretsky © (2005-03-01 12:58) [6]leonidus (01.03.05 12:41) [5]
Synchronize нужен только для синхронизации и к потокам отношения не имеет.
← →
sniknik © (2005-03-01 14:04) [7]> Описываю:
> ...
используемого компанента Parser1.Parse(MS1);
нет в описании, подозрение что он на форме лежит (визуальный?), вот это может быть причиной
> и результата ноль.
(хотя, ноль нолю рознь. интересно что ты под этим имееш ввиду.)
← →
leonidus (2005-03-01 14:18) [8]компонет визуальный, это да, он лежит на форме но ничего не отображает, просто в его событиях найденные в процессе парсинга ссылки добавляются в массив.
А ноль, я имел ввиду, что как загружала программа процессор на 100% так и загружает
← →
sniknik © (2005-03-01 14:34) [9]> компонет визуальный, ...
все, значит использовать в потоке нельзя. хотя на первый взгляд оно даже и работает.
> А ноль, я имел ввиду, что как загружала программа процессор на 100% так и загружает
а это не зависит от того где он работает (в каком потоке). зависит от того как написано, если он занимает все время не отдавая (sleep) другим процессам, и делая пустые циклы вместо ожиданий событий, то так и будет.
можеш попробовать приоритет потоку понизить, но вряд ли чтоизменится.
← →
leonidus (2005-03-01 14:48) [10]блин, это плохо... но вообще-то у меня на форме лежит четыре компонента idHTTP, и работают прекрасно в четырех потоках - качают одновременно... а может можно немного изменить код компонента Parser - у меня его исходники есть? Но как именно его надо модифицировать что бы он в потоках смогработать?
← →
leonidus (2005-03-01 19:18) [11]люди, не бросайте на произвол судьбы!
← →
Fay © (2005-03-01 19:20) [12]2 Anatoly Podgoretsky © (01.03.05 12:58) [6]
>> Synchronize нужен только для синхронизации и к потокам отношения не имеет.
Очень интересная мысль. А о синхронизации чего идёт речь?
← →
leonidus (2005-03-06 14:59) [13]Переделал. Теперь экземпляр Parser`а создаю в runtime прямо в потоке и к помпонентам лежащим на форме не обращаюсь. Выглядит код вот так:
type
//поток в котором будет запущен парсер
TParser1 = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
path:string;
end;
var
t_prs1:TParser1;
...
...
procedure TParser1.Execute;
var
MS1: TMemoryStream;
Prs1:TCDSParser;
begin
//в рантайме создаем Parser1
Prs1:= TCDSParser.Create(form1);
Prs1.OnTag:=form1.Parser1_Tag;
Prs1.OnText:=form1.Parser1_Text;
MS1:=TMemoryStream.Create;
MS1.LoadFromFile(t_prs1.path);
try
//запускаем парсер
Prs1.Parse(MS1);
except
end;
MS1.Free;
Prs1.Free;
end;
в теле программы, когда нужно запустить поток с парсером пишу:
t_prs1:=TParser1.Create(true);
t_prs1.path:=path;
t_prs1.Resume;
Все работает, но все равно наблюдается 100% загрузка ЦП во время парсинга, т.е. видимо в потоке все таки парсер не работает (хотя парсит - результаты парсинга получаются), в чем может быть проблема?
← →
sniknik © (2005-03-06 15:25) [14]> т.е. видимо в потоке все таки парсер не работает
если бы не работал то загрузки бы наоборот не былобы, и результато тоже.
раз уж есть исходники попробуй найти там цикл, тот в котором выполняется обработка (самый длительный должен быть), и поставь гденибудь там (в конце цикла например) sleep(0) работать будет дольше но полной загрузки уже не будет. (не должно быть).
но вообщето это не дело без кода заочно советовать что в нем исправить ;о)).
> но вообще-то у меня на форме лежит четыре компонента idHTTP, и работают прекрасно в четырех потоках - качают одновременно...
зря, я бы их тоже в поток перенес, туда где они работают.
← →
leonidus (2005-03-06 18:16) [15]Ок, попробую sleep поставить, там действительно есть большой цикл посимвольного перебора содержимого HTML-документа.
>зря, я бы их тоже в поток перенес, туда где они работают.
Ну так народ говорит, что если компонент лежит на форме то в потоке он работать не будет, однако повторю,у меня компоненты idHTTP несмотря на то что они лежат как раз таки на форме, прекрасно работают в потоке загружая процессор совсем чуть чуть.
Страницы: 1 вся ветка
Текущий архив: 2005.03.20;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.026 c