![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Предотвращение зависания программы [D6, WinXP]
leonidus © (2005-02-28 08:19:00)Ситуация следующая, в программе скачиваю последовательно несколько 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, но как быть тут, исходники парсера у меня есть (это сторонний компонент), но как их модифицировать что бы программа не так сильно подвисала?
leonidus (2005-03-06 18:16:00) [1]Ок, попробую sleep поставить, там действительно есть большой цикл посимвольного перебора содержимого HTML-документа.
>зря, я бы их тоже в поток перенес, туда где они работают.
Ну так народ говорит, что если компонент лежит на форме то в потоке он работать не будет, однако повторю,у меня компоненты idHTTP несмотря на то что они лежат как раз таки на форме, прекрасно работают в потоке загружая процессор совсем чуть чуть.
sniknik (2005-03-06 15:25:00) [2]> т.е. видимо в потоке все таки парсер не работает
если бы не работал то загрузки бы наоборот не былобы, и результато тоже.
раз уж есть исходники попробуй найти там цикл, тот в котором выполняется обработка (самый длительный должен быть), и поставь гденибудь там (в конце цикла например) sleep(0) работать будет дольше но полной загрузки уже не будет. (не должно быть).
но вообщето это не дело без кода заочно советовать что в нем исправить ;о)).
> но вообще-то у меня на форме лежит четыре компонента idHTTP, и работают прекрасно в четырех потоках - качают одновременно...
зря, я бы их тоже в поток перенес, туда где они работают.
leonidus (2005-03-06 14:59:00) [3]Переделал. Теперь экземпляр 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% загрузка ЦП во время парсинга, т.е. видимо в потоке все таки парсер не работает (хотя парсит - результаты парсинга получаются), в чем может быть проблема?
Fay (2005-03-01 19:20:00) [4]2 Anatoly Podgoretsky © (01.03.05 12:58) [6]
>> Synchronize нужен только для синхронизации и к потокам отношения не имеет.
Очень интересная мысль. А о синхронизации чего идёт речь?
leonidus (2005-03-01 19:18:00) [5]люди, не бросайте на произвол судьбы!
leonidus (2005-03-01 14:48:00) [6]блин, это плохо... но вообще-то у меня на форме лежит четыре компонента idHTTP, и работают прекрасно в четырех потоках - качают одновременно... а может можно немного изменить код компонента Parser - у меня его исходники есть? Но как именно его надо модифицировать что бы он в потоках смогработать?
sniknik (2005-03-01 14:34:00) [7]> компонет визуальный, ...
все, значит использовать в потоке нельзя. хотя на первый взгляд оно даже и работает.
> А ноль, я имел ввиду, что как загружала программа процессор на 100% так и загружает
а это не зависит от того где он работает (в каком потоке). зависит от того как написано, если он занимает все время не отдавая (sleep) другим процессам, и делая пустые циклы вместо ожиданий событий, то так и будет.
можеш попробовать приоритет потоку понизить, но вряд ли чтоизменится.
leonidus (2005-03-01 14:18:00) [8]компонет визуальный, это да, он лежит на форме но ничего не отображает, просто в его событиях найденные в процессе парсинга ссылки добавляются в массив.
А ноль, я имел ввиду, что как загружала программа процессор на 100% так и загружает
sniknik (2005-03-01 14:04:00) [9]> Описываю:
> ...
используемого компанента Parser1.Parse(MS1);
нет в описании, подозрение что он на форме лежит (визуальный?), вот это может быть причиной
> и результата ноль.
(хотя, ноль нолю рознь. интересно что ты под этим имееш ввиду.)
Anatoly Podgoretsky (2005-03-01 12:58:00) [10]leonidus (01.03.05 12:41) [5]
Synchronize нужен только для синхронизации и к потокам отношения не имеет.
leonidus (2005-03-01 12:41:00) [11]Может я Synchronize не исползовал поэтому поточность не работает? Но куда его поставить ума не приложу
leonidus (2005-03-01 11:30:00) [12]Описываю:
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;
и результата ноль. Помогите пожалуйста!
sniknik (2005-03-01 11:25:00) [13]примеров валом, даже здесь
http://www.delphimaster.ru/cgi-bin/forum.pl?n=0&search=TThread
leonidus (2005-03-01 11:22:00) [14]пробовал но нвсе равно не удается, хотя я не силен в потоках. Можно примерчик?
КаПиБаРа (2005-02-28 08:21:00) [15]Идеально было бы запускать его в отдельном потоке.