Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];

Вниз

По поводу Application.ProcessMessages   Найти похожие ветки 

 
ИМХО   (2004-01-06 18:27) [0]

Недавно прочитал в какой-то статье, посвященной программированию в среде Delphi, что в нормальном приложении Application.ProcessMessages вообще не должно быть. Видимо, имелось в виду, что нужно обходиться другими методами. Как бы вы прокомментировали это?


 
MBo   (2004-01-06 18:44) [1]

Application.ProcessMessages - в некотором смысле "подпорка" для быстрого написания простых программ. Часто разумно выносить расчеты в отдельный поток.


 
YuRock   (2004-01-06 18:49) [2]

ProcessMessages используется при необходимости выкрутить сообщения. При чем здесь "нормальное приложение", не понятно...


 
Тимохов   (2004-01-06 18:50) [3]

Скажу по своему опыту, что Application.ProcessMessages чрезвычайно вредная вешь при навернутой программе. Иногда бывают такие фокусы, что не сразу разберешь, что к чему.
Но все равно использую, т.к. пока нет времени разнести все по потокам...


 
jack128   (2004-01-06 19:00) [4]

Чем проще программа, тем лудше использовать Application.ProcessMessages, ибо нефиг излишне усложнять программу потоками...


 
Тимохов   (2004-01-06 19:02) [5]

jack128 © (06.01.04 19:00) [4]

ProcessMessages все-таки коварная штука.
Чессо слово тяжело сейчас строить пример, несмотря на то, что я его хорошо помню. Но уверен, что некоторое время он любого вы ввел в заблуждение.

Сухой остаток: юзать можно, но осторожно.


 
ИМХО   (2004-01-06 19:02) [6]

А как это делать (насчет отдельных потоков)?

Я, например, использую Application.ProcessMessages для того, чтобы отображались показания таймера во время работы какой-то процедуры.


 
Vlad   (2004-01-06 19:11) [7]


> ИМХО © (06.01.04 19:02) [6]


TThread + F1.
И еще в FAQ есть кое какая инфа, даже с кодом.


 
jack128   (2004-01-06 19:39) [8]


>
> Тимохов © (06.01.04 19:02) [5]
> jack128 © (06.01.04 19:00) [4]
>
> ProcessMessages все-таки коварная штука.
> Чессо слово тяжело сейчас строить пример, несмотря на то,
> что я его хорошо помню. Но уверен, что некоторое время он
> любого вы ввел в заблуждение.
Думаю пример был бы в том что несколько обработчиков сообщений изменяют одну и туже глобальную переменную.

например
var
obj: TMyClass = nil;

procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(obj);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
obj := TMyClass.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
while .... do
begin
obj.SameMethod; // если нажать вторую кнопку, то выход по AV
Application.BrocessMessages;
end;
end;
Но с потоками и синхронизацией доступа к данным мороки еще больше


 
Anatoly Podgoretsky   (2004-01-06 19:49) [9]

Ну и какое отношение это глюкавый код имеет к якобы глюкавому Application.BrocessMessages.


 
Игорь Шевченко   (2004-01-06 19:49) [10]

Вот есть такая программка IBConsole. Вроде, нормальное приложение. Есть ее исходники. Application.ProcessMessages используется. Есть Demos от Borland - Application.ProcessMessages используется.

Авторы хотят выглядеть святее, чем Папа Римский.
Так что читать такие статьи лучше с включенной головой.


 
jack128   (2004-01-06 19:52) [11]


> Anatoly Podgoretsky © (06.01.04 19:49) [9]
> Ну и какое отношение это глюкавый код имеет к якобы глюкавому
> Application.BrocessMessages.
Да водщем то никакого. Это доказательство того, что имея достаточно кривые руки можно написать глюкавый код в пять строк ;-)


 
Тимохов   (2004-01-06 19:54) [12]

Игорь Шевченко © (06.01.04 19:49) [10]
Немного грубовато имхо.

Всем.
в [8] есть пример ошибки. Может случить там, что obj отдестроиться, когда цикл еще не кончился.
У меня действительно была схожая ситуация, только такм был не цикл, а рекурсия.

jack128
Ценю проницательность :)


 
Anatoly Podgoretsky   (2004-01-06 19:55) [13]

Конечно можно, но почти тотже код без Application.BrocessMessages даст тот же самый результат.

procedure TForm1.Button1Click(Sender: TObject);
begin
obj.SameMethod;
// нажать вторую кнопку, затем первую


 
Тимохов   (2004-01-06 19:56) [14]

Anatoly Podgoretsky © (06.01.04 19:49) [9]
И вообще никто не говорил, что processmessages имеет глюки.
Просто он таит в себе определенные опасности при кривых, как было сказано выше, руках.


 
Тимохов   (2004-01-06 19:57) [15]

Anatoly Podgoretsky © (06.01.04 19:55) [13]
Думаю все-таки ясно в чем была суть примера. ИМХО Вы издеваетесь. :)


 
Anatoly Podgoretsky   (2004-01-06 19:58) [16]

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


 
Тимохов   (2004-01-06 20:01) [17]

Anatoly Podgoretsky © (06.01.04 19:58) [16]
Думаю надо согласиться на том, что данный пример подразумевает нажатие сначала первой кнопки. И пока там идет while нажатие второй кнопки. Думаю, что пример обладает некой недоделанностью. Но суть обсуждаемого вопроса показывает полностью.


 
Anatoly Podgoretsky   (2004-01-06 20:10) [18]

Показывает только безобразно написаный код и не более.


 
Игорь Шевченко   (2004-01-06 20:12) [19]

Тимохов © (06.01.04 19:56)


> никто не говорил, что processmessages имеет глюки.
> Просто он таит в себе определенные опасности при кривых,
> как было сказано выше, руках.


А при кривых руках, уважаемый, на помощь приходит выпрямитель рук, называемый отладчиком или WinSight"ом(для просмотра сообщений). Если вы молотком по пальцу попадете, забивая гвоздь, вы же не станете писать статью о вреде использования молотка ;)


 
Тимохов   (2004-01-06 20:27) [20]

Игорь Шевченко © (06.01.04 20:12) [19]
Anatoly Podgoretsky © (06.01.04 20:10) [18]

Ладно, чтобы пояснить свою мысль прведу свой код.
Есть SomeAction выполняемая по клавише F5.
Пользователь нажимает на эту клавишу в течении одной минуты. Потом сразу нажимает крестик в углу форма (т.е. close)
Вот упрощенный код.

procedure tform1.SomeActionExecute(...)
begin
if SomeHeavyDatabaseQuery <> nil then
begin
Application.ProcessMessages();
SomeHeavyDatabaseQuery.Execute();
end;
end;

destructor tform1.Destroy();
begin
FreeAndNil(SomeHeavyDatabaseQuery);
end;

Что здесь происходит.
Когда пользователь жмет f5, то прога может дойти до Application.ProcessMessages(). После чего не пойдет дальше а снова попадет в этот же обработчик. И так раз сто. При этом образуется полноценный (т.е. дельфовый, а не ивентный) стек вызовов. Когда пользователь вызывает close, то он делается releasom, т.е. тоже через посыл сообщения. Этот ивент радостно отрабатывает, после чего выполнение программы возвращается на строку SomeHeavyDatabaseQuery.Execute(). Здесь и происходит АВ.

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

В описанной ситуации будет ошибка. Ясно, что это ошибка программиста, но все же она не вполне очевидна.


 
Бином Ньютоныч   (2004-01-06 20:40) [21]

>нормальном приложении Application.ProcessMessages вообще не должно быть.

имхо чушь полная. Нормальный способ обработать очередь, причем с учетом всех особенностей VCL. Длительные расчеты не единственный случай. Например, ждем события с помощью MsgWait... в VCL-проге - что тут лучше, чем ProcessMessages? А создавать потоки на каждый чих - имхо глупость, потому как создание потока - одна из самых ресурсоемких операций. К тому же в 9х реализация многопоточности, мягко говоря, не очень удачная, только времени на переключение потоков уходит чуть не столько-же, сколько и на работу


 
Anatoly Podgoretsky   (2004-01-06 20:55) [22]

Она вполне очевидна, неверная последовательность операторов, если же нужна именно эта последовательность, то проверять надо после Application.ProcessMessages(); иначе получается некоторая самоуверенность, попытка использования переменной или поля с непредсказуемым содержимым.

Кривые руки никак не доказывают недостатков Application.ProcessMessages, народ умудряется работать с объектами вообще их не создавая. Данный метод ни чем не хуже других неверно используемых средств. Сам метод как раз и предусмотрен, чтобы обработать сообщения системы, еще с времен Windows 1.0, а многозадачная среда накладывает свой отпечаток.


 
Anatoly Podgoretsky   (2004-01-06 20:58) [23]

Бином Ньютоныч (06.01.04 20:40) [21]
Ресурсоемкость да бог с ней, а вот с потоками столько ошибок наделают, что всю систему на колени поставят. Потоки нужны для выполнения паралельной работы.вычислений, но никак не для обработки сообщений.


 
Бином Ньютоныч   (2004-01-06 21:13) [24]

>Anatoly Podgoretsky © (06.01.04 20:58) [23]
Ну вообще-то я имел в виду вариант с выносом ожидания в отдельный поток:) В смысле вовсе не всегда это оптимально


 
Anatoly Podgoretsky   (2004-01-06 21:22) [25]

Конечно не оптимально, если другие потоки не будут делать полезную работу, а что бы двигать форму, нажимать на ней кнопки нет нужды их делать.


 
Тимохов   (2004-01-08 11:26) [26]

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

Но, все-таки хочется подвести итог данному обсуждению.

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

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

Но! В качестве итога считаю привести следующую фразу: в нормальный приложениях место ProcessMessages есть, только надо понимать, что это может принести некторые не очевидные для большинства программистов среднего уровня проблемы. Считаю, что пример [20] впролне это доказывает (Анатолию - да кривые руки там есть, но не все же так талантливы, чтобы сразу понять, что там ошибка.).

Одним словом - использовать ProcessMessages можно, но осторожно.


 
Игорь Шевченко   (2004-01-08 12:14) [27]

Тимохов © (08.01.04 11:26)


> использовать ProcessMessages можно, но осторожно


Использовать операторы + и - тоже можно, с не меньшей осторожностью. Смешно, ей-богу.
Извините, наболело. Почему не попытаться понимать, прежде чем что-то программировать, как оно вообще работает ? Довольно много "проблем" сразу исчезает.


 
Тимохов   (2004-01-08 12:19) [28]

Игорь Шевченко © (08.01.04 12:14) [27]

Смешного ничего здесь не вижу.
И вообще, обещаю, что в следующий раз при обсуждении не вполне очевидного момента после приведения ошибочного кода не буду давать комментарий почему он ошибочен. Интересно, сдюжат ли мастера прорюхать что к чему? :)))

И вообще, все, что нужно по данному вопросу счию уже сказано.


 
int64   (2004-01-09 12:17) [29]

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

Вот об этом и весь разговор: о преймуществе второго метода. :)


 
BlackTiger   (2004-01-09 16:20) [30]

Чёй-то вы фигней тут, имхо, занимаетесь. ProcessMessages использовать НУЖНО, но только там, где нужно. Сколько раз мне помогал его VB-аналог "DoEvents"!

Он помогает НЕ ЗАВЕШИВАТЬ приложение (точнее его интерфейс) при большом количестве итераций или при медленных итерациях в цикле.


 
Тимохов   (2004-01-09 16:27) [31]

BlackTiger © (09.01.04 16:20) [30]

Т.к. я могу также крикнуть "ИСПОЛЬЗОВАТЬ НУЖНО, НО ТОЛЬКО ТАМ ГДЕ НУЖНО". :)))
Одним словом - я считаю точно также как вы.

Про "занимаетесь фигней", имхо считаю, что Вы не тактичны. Считаю, что скорее фигней занимаетесь Вы т.к. повотрили неоднократно выше приведенное утверждение.


 
Fantasist   (2004-01-10 02:27) [32]


> использовать ProcessMessages можно, но осторожно.


Использовать потоки можно, но осторожно. Использовать RPC
можно, но осторожно. Использовать dll"ки можно, но осторожно.

Программировать можно, но осторожно. Ибо проблему можно создать везде, если не понимаешь с чем работаешь.


 
olookin   (2004-01-10 10:26) [33]

Лично я использую Application.ProcessMessages не просто там где попало, а только там, где пользователю вообще не предоставлена возможность нажать Close или сделать нечто подобное... Как правильно заметил BlackTiger[30] - это незаменимая вещь для "незавешивания" программы при выполнении долгих расчетов, или например для индикации таких расчетов. Что я и делаю - у меня Application.ProcessMessages служит только для индикации процесса вычисления. При этом форма-индикатор у меня модальная и не имеет кнопок системного меню... При этом замечу насчет возможных высказываний в духе "...надо позволить во время расчета пользователю еще чего то делать, типа другой расчет включить..." - мне потоки не нужны, поскольку у меня не "многорасчетная" программа, а если кому нужны - то Application.ProcessMessages все равно тут ни причем...

Так что примкну к мнению Тимохова - можно... Может быть даже не так осторожно, как предлагается... Чай не совсем дураки же те, кто садится за написание программы...

(а почему ветка до сих пор не в Потрепаться? "Последняя половина" сообщений принимает характер личного обсуждения...)


 
Вован_   (2004-01-10 12:01) [34]

Сорри, возможно скажу глупость, т.к. к мастерам Дельфи я наверное совсем не принадлежу. Однако, у меня есть парочка многопоточных программ, где паралельный поток вызывается в тех местах, где нужно ускорение для вычислений, т.е. разбиение вычисления на два независимых этапа и пуск одновременно обоих этапов - одного в общем потоке, другого - в созданном.
Application.ProcessMessages в этих своих прогах я начал использовать лишь только тогда, когда понял, что оно нужно для самостоятельного закрывания программы при завершении сеанса Винды. И по сей день я больше не вижу в нем никакой другой прикладной нужды:)



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

Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.012 c
14-63347
Clift
2003-12-30 01:41
2004.01.20
string+Image=ОДИН файл


1-63201
ИМХО
2004-01-10 05:09
2004.01.20
Системы счисления


1-63135
Ландграф Павел
2004-01-06 21:03
2004.01.20
Регистрация dll/ocx без REGSVR32.EXE


14-63365
Dolot
2003-12-29 00:30
2004.01.20
Работа с systray ем


14-63304
Агент Смит [8]
2003-12-26 23:52
2004.01.20
В милицию замели. Дело шьют. (ц) end;





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский