![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Application.ProcessMessages и загрузка процессора
Pcrepair © (2012-05-27 11:27:00)Добрый день
Замечено, что в момент загрузки страницы ПРОЦ грузит до 50% видимо в первом Application.ProcessMessages
try
Wbbr.Navigate(UrlSearch, Flags, TargetFrameName, PostData, Headers);
repeat
Application.ProcessMessages; (*видимо тут грузит проц до 50%*)
until Wbbr.ReadyState >= READYSTATE_COMPLETE;
if Wbbr.Document <> nil then
HtmlCodeData := AnsiLowerCase(
(Wbbr.Document as iHTMLDocument2).body.innerhtml);
Application.ProcessMessages; (*тут вроде бы и не надо?*)
except
CodeSite.EnterMethod( Self, 'Timer' );
CodeSite.SendError('TWebBrowser failed'); (*бравузер здох*)
CodeSite.ExitMethod( Self, 'Timer' );
end;
Вопрос: чем можно заменить Application.ProcessMessages в коде, так чтобы гарантировать загрузку страницы перед выполнением последующих инструкций
Плохиш (2012-06-01 15:20:00) [1]
> Отключение Enabled, не спасает, если в очереди уже есть
> таймерные сообщения.
Сообщения от таймера не дублируются, по-стандарту используемой ОС.
Anatoly Podgoretsky (2012-06-01 06:47:00) [2]> Loginov Dmitry (31.05.2012 23:21:34) [34]
Enabled как раз и отключает, сообщение остается в очереди
Loginov Dmitry (2012-05-31 23:21:00) [3]
> такие вещи делают не флагом, а с помощью Enabled и без
> какой либо проверки.
Отключение Enabled, не спасает, если в очереди уже есть таймерные сообщения. Не помню где, но на этом приходилось спотыкаться.
Надежнее обработчик отключить:
Timer1.OnTimer := nil;
try
...
finally
Timer1.OnTimer := .....;
end;
Sha (2012-05-31 09:48:00) [4]> Max (31.05.12 01:40) [28]
> ты имеешь ввиду часть вызовов таймера?
> ну так можно завести другой таймер
Таймер тут вообще ни при чем, это просто пример обработчика сообщения.
Речь идет вообще об опасности вызова ProcessMessages из процедуры обработки сообщения, т.е. об опасности вложенных вызовов ProcessMessages.
> 3,4 не совсем понял, подозреваю, что чего-то не понимаю :)
Имеется в виду, что у тебя внутри обработки одного сообщения начинается обработка других. Это может быть опасно, т.к., во-первых, главная форма, все что на ней и, может быть, не на ней, - общие переменные, которые никак не защищены и могут быть использованы непредсказуемо. Во-вторых, отрисовка чего-то одного внутри другого также опасна. В-третьих, могут быть логически нестыковки, например, когда внутри обработки результатов запроса ты позволяешь пользователю послать еще десяток. В-четвертых, могут быть проблемы с другими компонентами, когда кто-то другой может не рассчитывать, что его код будут вызывать подобным образом, или наоборот, может думать, что один во вселенной, кому позволено так вызывать.
Возможно, всех этих проблем у тебя пока нет. Пока нет.
Sha (2012-05-31 09:23:00) [5]> sniknik © (31.05.12 08:02) [30]
и, да, переводчики часто теряют контекст
Sha (2012-05-31 09:09:00) [6]Это обсуждение, показывающее, что одна глупость тянет за собой кучу других.
sniknik (2012-05-31 08:02:00) [7]>> как-то надо будет защитить все другие места вызова ProcessMessages, если они есть
> ну само собой
перевод:
> для нормальной работы кода с ProcessMessages, нужно сделать так чтобы он не вызывался ни в одной из возможный ситуаций.
> ну само собой
???
и это обсуждение к примеру показывающему, что ProcessMessages использовать не нужно... нда.
Anatoly Podgoretsky (2012-05-31 06:28:00) [8]> Max (31.05.2012 00:47:26) [26]
Хреновый пример, такие вещи делают не флагом, а с помощью Enabled и без
какой либо проверки.
Timer1.Enabled := False;
try
А пример у Sha нормальный, демонстрирует то что нужно
Max (2012-05-31 01:40:00) [9]
> как-то надо будет защитить все другие места вызова ProcessMessages,
> если они есть
ну само собой
> часть сообщений ты потеряешь, а они могут быть нужны
ты имеешь ввиду часть вызовов таймера? ну так можно завести другой таймер, где нет тяжелой обработки или может вообще нить отдельную (я ж не знаю о какой задаче говорим)
3,4 не совсем понял, подозреваю, что чего-то не понимаю :)
Sha (2012-05-31 01:21:00) [10]> Max (31.05.12 00:47) [26]
при этом ты избавился от вложенных вызовов ProcessMessages в данном месте, но
1. как-то надо будет защитить все другие места вызова ProcessMessages, если они есть
2. часть сообщений ты потеряешь, а они могут быть нужны
3. не факт, что процедура, вызванная из ProcessMessages, не навредит текущей, т.к. у них есть общие глобальные переменные
4. ты теряешь контроль над ходом и временем выполнения
Max (2012-05-31 00:47:00) [11]
> Какой флажок
такой
var
Count: integer;
BusyFlag: boolean = False;
procedure Tblazar.Timer1Timer(Sender: TObject);
var
i: integer;
begin;
if BusyFlag then exit;
BusyFlag := True;
try
//ваша имитация
Count:=0;
for i:=1 to 3 do
begin
Sleep(Random(500));
inc(Count);
Application.ProcessMessages;
end;
Memo1.Lines.Add(IntToStr(Count));
finally
BusyFlag := False;
end;
end;
> ты понял о чем пример
что там может быть не понятного?
Sha (2012-05-31 00:12:00) [12]> Max (30.05.12 23:58) [24]
> так а зачем ProcessMessages из таймера вызывать?
Ну, если тебе не лень нажимай кнопку, а я ленивый.
> в крайнем случае можно флажок завести
Какой флажок, ты понял о чем пример?
Max (2012-05-30 23:58:00) [13]
> может, после этого примера ты разлюбишь Application.ProcessMessages
так а зачем ProcessMessages из таймера вызывать? в крайнем случае можно флажок завести
Сергей М. (2012-05-30 22:37:00) [14]
> sniknik © (28.05.12 23:47) [16]
Да пОхрену)
Для автора, полагаю, важнее будет понимание того что все велосипеды уже изобретены и выглядят они вполне изящно - достаточно не полениться жмакнуть F1
Германн (2012-05-30 02:15:00) [15]Давай жить дружно! (с) Кот Леопольд.
Не отвечай на мои высказывания после полуночи . Лучше ответь на следующее утро.
Sha (2012-05-30 01:53:00) [16]Интересная мысль.
Теперь все знают, что надо делать с инструментами.
Германн (2012-05-30 01:07:00) [17]
> Sha © (29.05.12 12:11) [19]
>
> > Pcrepair
>
> может, после этого примера ты разлюбишь Application.ProcessMessages
Фетишист?
Разве обязательно любить (или не любить) инструмент? Инструменты надо правильно использовать, зная их возможности и особенности. Только и всего. :)
Sha (2012-05-29 12:11:00) [18]> Pcrepair
может, после этого примера ты разлюбишь Application.ProcessMessages
//демонстрация возможной ошибки при использовании Application.ProcessMessages
var
Count: integer;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin;
//имитация вычислений
Count:=0;
for i:=1 to 3 do begin;
Sleep(Random(800));
inc(Count);
Application.ProcessMessages;
end;
//показываем результат
Memo1.Lines.Add(IntToStr(Count));
end;
Германн (2012-05-29 01:45:00) [19]
> То что смысл высказывания sniknik не имеет никакого отношения
> к ООП
Тут я несколько погорячился, конечно. :)
Германн (2012-05-29 01:36:00) [20]
> он подменяет событийность, с оповещением на линейность с
> мониторингом...
Просто никто на всех тех форумах, где он задал вопрос, не дал ему никакого готового кода, кроме Sleep (1);
P.S.
Мне вот интересно. Pcrepair и leklerk это разные люди в реале? Или это один и тот же персонаж? И тот и другой забрасывают свои вопросы одновременно на кучу форумов по Дельфи в надежде, что хоть где-нибудь дадут код. Спрашивают правда про разное, но как-то удивительно синхронно.
P.P.S.
А уж сегодня ещё одно странное совпадение.
После ответа
> sniknik © (28.05.12 18:09) [10]
на вопрос Pcrepair в данной ветке, leklerk менее чем через 50 минут задал вопрос "Когда нужно использовать ООП?" http://www.delphimaster.ru/cgi-bin/forum.pl?id=1338216754&n=18
То что смысл высказывания sniknik не имеет никакого отношения к ООП - значения не имеет, ибо и Pcrepair и leklerk в данной теме совершенно не разбираются!