Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.29;
Скачать: CL | DM;

Вниз

Не прорисовывается окно   Найти похожие ветки 

 
Юрий Зотов ©   (2004-02-17 10:38) [40]

> For TempIdx:=1 To 5 Do Application.ProcessMessages;

Это опечатка или шутка?

Что это просто ошибка - не верю. Потому что человек, рассуждающий о потоках, процессах, квантах, приоритетах и пр. ТАК ошибаться не может.


 
Defunct ©   (2004-02-17 10:39) [41]

Нет это не ручной тормоз, просто посмотри сколько раз App.ProcMsg вызовется на фоне всех вычислений.

Че говорить, я уже устал спорить:
Если интересно, запусти и посмотри как работает.
Убери цикл, запусти и посмотри реакцию других приложений.

Ну и сравни результат. Я прежде чем постить пример, проверил и так и так.


 
Sphinx ©   (2004-02-17 10:41) [42]

Ну я не спорю, код не оптимален, НО
> For TempIdx:=1 To 5 Do Application.ProcessMessages
Я не понял :( Зачем вызывать эту процедуру пять раз подряд?
Ti изначально равно TBegin, правда расчет ведется с нуля, а с TBegin только вывод на Chart.

> If Frac(Ti)<dt Then // может быть dt*10
И что получим? Условие будет срабатывать 9 раз из 10 (если dt*10) или ни разу так как Ti увеличивается на dt в каждом цикле а значит его дробная часть не может быть меньше шага приращения.

Далее, внимательней читайте ответы!!! Я уже говорил, что можно сделать вывод инфы и обновление формы каждый десятый (пятый и т.д.) цикл, но это не выход, потому, что шаг и промежуток TEnd-TBegin не постоянны, они задаются на основной форме, а значит для какого-то варианта может возникнуть ситуация что цикл выполняется скажем 9 раз. И если выводить информацию каждый десятый, то получим бяку. Что меня не устраивает!!! Нужна универсальность.

И на мой взгляд, то что Вы предложили проще сделать так:
TempIdX:=0
repeat
...
Inc(TempIdX);
If TempIdX>9 then
begin
Application.ProcessMessages;
TempIdX:=0;
end;
...
until ...


 
Defunct ©   (2004-02-17 10:43) [43]

Да, но только число будет не 9, а 10000


 
Плохиш   (2004-02-17 10:44) [44]

>Sphinx © (17.02.04 10:41) [42]

> Я уже говорил, что можно сделать вывод инфы и обновление
> формы каждый десятый (пятый и т.д.) цикл, но это не выход,
> потому, что шаг и промежуток TEnd-TBegin не постоянны, они
> задаются на основной форме, а значит для какого-то варианта
> может возникнуть ситуация что цикл выполняется скажем 9
> раз. И если выводить информацию каждый десятый, то получим
> бяку. Что меня не устраивает!!! Нужна универсальность.

А посчитать шаг обновления формы перед вычислениями, что уже кем-то запрещено?


 
Defunct ©   (2004-02-17 10:48) [45]

Юрий Зотов © (17.02.04 10:38) [40]
> Это опечатка или шутка?
Ни то, ни другое.
Сами попробуйте, напишите без цикла и с циклом, если не заметите разницы, можете говорить, об ошибке или поместить очередной пост в "Потрепаться".


 
Sphinx ©   (2004-02-17 10:53) [46]


> Плохиш (17.02.04 10:44) [44]
> А посчитать шаг обновления формы перед вычислениями, что уже кем-то запрещено?

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


> Да, но только число будет не 9, а 10000
Я суть потерял, это к какому именно числу (в каком ответе и месте этого ответа)

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


 
Alex Konshin ©   (2004-02-17 10:54) [47]

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


 
Defunct ©   (2004-02-17 10:55) [48]

>> Да, но только число будет не 9, а 10000
>Я суть потерял, это к какому именно числу (в каком ответе и месте этого ответа)


TempIdX:=0
repeat
...
Inc(TempIdX);
If TempIdX> 10000 then
begin
Application.ProcessMessages;
TempIdX:=0;
end;


 
Юрий Зотов ©   (2004-02-17 10:57) [49]

> Defunct © (17.02.04 10:48) [45]

> Cами попробуйте, напишите без цикла и с циклом, если не
> заметите разницы, можете говорить, об ошибке или поместить
> очередной пост в "Потрепаться".

А если действительно попробую, действительно замечу разницу, докопаюсь до ее ИСТИННЫХ причин и таки напишу обо всем об этом в "потрепаться"? Вы представляете, ЧТО и я там напишу? И представляете, КАК напишу - после всех этих споров?


 
Defunct ©   (2004-02-17 10:59) [50]

Опять же, все-таки поставьте там

TempIdX:=0
repeat
...
Inc(TempIdX);
If TempIdX> 10000 then
begin
For I:=1 To 5 Do Application.ProcessMessages;
TempIdX:=0;
end;


Иначе в других приложениях нельзя будет открыть даже пункта меню.
Ваша, форма будет вполне нормально реагировать на все события и при однократном вызове App.ProcMsg


 
Romkin ©   (2004-02-17 11:02) [51]

В Execute нет Syncronize при обращении к Progressbar...


 
AKul ©   (2004-02-17 11:04) [52]


> Defunct © (17.02.04 10:59) [50]
> Иначе в других приложениях нельзя будет открыть даже пункта
> меню.
> Ваша, форма будет вполне нормально реагировать на все события
> и при однократном вызове App.ProcMsg

Причем тут другие приложения???
Вы что под win3.1 пишите???


 
Defunct ©   (2004-02-17 11:06) [53]

Юрий Зотов © (17.02.04 10:57) [49]
А если действительно попробую, действительно замечу разницу, докопаюсь до ее ИСТИННЫХ причин и таки напишу обо всем об этом в "потрепаться"? Вы представляете, ЧТО и я там напишу? И представляете, КАК напишу - после всех этих споров?


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


 
Alex Konshin ©   (2004-02-17 11:07) [54]

До меня дошло.
Ты действительно думаешь, что Application.ProcessMessages обрабатывает только одно сообщение?!

Не, это точно в морг, даже вскрытия не надо.


 
Sphinx ©   (2004-02-17 11:08) [55]

> If TempIdX>10000 then
Да ё, что ж это такое!!! Defunct © (17.02.04 10:55) [48] Вы вообще как читаете что именно пишут тут? Если воткнуть такое число, то получим для того примера что я привел 75 обновлений, это я согласен нормально, но это один из 30 примеров, так сказать тот на котором все тестируется, возможна ситуация когда цикл выполнится 9 раз!!! Можно, как предложил Плохиш сосчитать это число как шаг обновления формы, но не нравится мне этот метод!!!


 
Digitman ©   (2004-02-17 11:10) [56]


> Defunct © (17.02.04 10:28) [38]


"Вы не любите кошек ? Да Вы их просто готовить не умеете !" (С)

реализация поточного класса у тебя хромает на все ноги, налицо - грубые ошибки, связанные с синхронизацией обращений к VCL-контролам, и с конструированием/инициализацией объекта TMyThread

сомневаюсь, что это вообще у тебя работает .. этот обязательно приведет к исключительной ситуации вплоть до краха процесса !


 
Alex Konshin ©   (2004-02-17 11:11) [57]

И еще: какое отношение ProcessMessages имеет к обработке сообщений в других приложениях?
Это я на этот пост намекаю:
Defunct © (17.02.04 10:59) [50]


 
AKul ©   (2004-02-17 11:13) [58]


> Defunct © (17.02.04 10:59) [50]

Это Вы можете найти у себе в исходном тексте модуля Forms.pas^

procedure TApplication.ProcessMessages;
var
Msg: TMsg;
begin
while ProcessMessage(Msg) do {loop};
end;

Я думаю Вам понятно значение выделенных жирным операторов?

А вот что Вы подрузумевали под

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

Я до сих пор понять не могу???
Причем тут другие приложения. Объясните же наконец.


 
Sphinx ©   (2004-02-17 11:14) [59]

> Иначе в других приложениях нельзя будет открыть даже пункта
> меню
Ну не понимаю я зачем вызывать эту процедуру пять раз!!! Все работает и с однократным вызовом. Код я приводил из одной из версий программы РАБОТОСПОСОБНЫЙ, но не факт что оптимальный.


 
Defunct ©   (2004-02-17 11:30) [60]

Alex Konshin © (17.02.04 11:07) [54]
До меня дошло.
Ты действительно думаешь, что Application.ProcessMessages обрабатывает только одно сообщение?!


Нет я так не думаю. Я думаю, что один вызов ProcessMessages не отчищает очередь событий.

> Да ё, что ж это такое!!! Defunct © (17.02.04 10:55) [48]
Не хочу ни о чем спорить.
Делайте через Thread. цикл 9 раз!!! , иначе конечно ~10 сек вычислений будет жутко некрасиво и медленно.

>реализация поточного класса у тебя хромает на все ноги, налицо - грубые ошибки, связанные с синхронизацией обращений к VCL-контролам, и с конструированием/инициализацией объекта TMyThread
;)
Цель была проверить скорость, а не писать безглючный TMyThread.


 
AKul ©   (2004-02-17 11:37) [61]


> Defunct © (17.02.04 11:30) [60]
> Нет я так не думаю. Я думаю, что один вызов ProcessMessages
> не отчищает очередь событий.

Посмотрите внимательнее на мой пост AKul © (17.02.04 11:13) [58]
Там содержится ответ на Ваш вопрос, если Вы конечно понимате конструкцию While <cond> do...

И убедительная просьба ответить на последний вопрос того ([58]) поста:

"Причем тут другие приложения? Объясните же наконец."


 
Alex Konshin ©   (2004-02-17 11:38) [62]

Нет я так не думаю. Я думаю, что один вызов ProcessMessages не отчищает очередь событий.
???
А что же он делает по-твоему? Почитай на досуге:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandm essagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/peekmessage.asp
Особенно обрати внимание на PM_REMOVE


 
Verg ©   (2004-02-17 11:42) [63]

Да че тут спортиь-то:

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;

procedure TApplication. ProcessMessages;
var
Msg: TMsg;
begin
while ProcessMessage(Msg) do {loop};
end;


 
Romkin ©   (2004-02-17 11:44) [64]

Ну и ссылочка. Вот это послал :)))
Вообще, веселая ветка получилась. В Орешник бы...


 
Alex Konshin ©   (2004-02-17 11:46) [65]

Verg © (17.02.04 11:42) [63]
Ты другим не мешай веселится, раз сам не хочешь :)


 
Digitman ©   (2004-02-17 11:58) [66]


> Цель была проверить скорость, а не писать безглючный TMyThread.


а что ее проверять ?

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

так что ерундой ты с "проверкой скорости" занялся)


 
Defunct ©   (2004-02-17 11:59) [67]

AKul © (17.02.04 11:37) [61]
> Я до сих пор понять не могу???
> Причем тут другие приложения. Объясните же наконец.


Но ведь наглядно видно, как другие приложения тормозят!
Как это объяснить?

Может kernel32/user32 что-то выполняют?
Может я торможу?


 
Sphinx ©   (2004-02-17 12:06) [68]

> Но ведь наглядно видно, как другие приложения тормозят!
Не тормозят! Погодите, а комп у Вас какой??? Не Пень100 случаем :)


 
KSergey ©   (2004-02-17 12:09) [69]

Люди!! Епрст...
А что, читать соседние ветки - это уже никто совсем не хочет?
А то прямо поветрие - это уже 3-я ветка на данную тему за последние дни!

http://delphimaster.net/view/1-1076671800/
http://delphimaster.net/view/1-1076671800/
http://delphimaster.net/view/1-1076671800/


 
AKul ©   (2004-02-17 12:13) [70]


> Defunct © (17.02.04 11:59) [67]
>
> Но ведь наглядно видно, как другие приложения тормозят!
> Как это объяснить?
>
> Может kernel32/user32 что-то выполняют?
> Может я торможу?

Это можно объяснить несколькими причинами:

Вы используете Win 3.1x. - Маловероятно.

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

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

Остается еще один вариант, Ваша цитата:
> Может я торможу?
Возможный ответ на этот вопрос, я думаю, Вы знаете сами.

P.S. Да будет Вам известно, что каждый поток имеет свою очередь сообщений, и выборку этих сообщений он делает сам, так что "зависание" одного потока, никак не повлияет на выборку сообщений другими потоками.


 
Alex Konshin ©   (2004-02-17 12:14) [71]

Не мешай - в этой ветке веселее.


 
Digitman ©   (2004-02-17 12:18) [72]

> Defunct © (17.02.04 11:59) [67]
> Но ведь наглядно видно, как другие приложения тормозят!
> Как это объяснить?

не ставь tpTimeCritical - тормозить не будут

> Может kernel32/user32 что-то выполняют?

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

а если уж ты так шибко переживаешь за произв-ть своего цикл.алгоритма в доп.потоке, то здесь просто следут пересмотреть сам алгоритм, и во всех "узких" местах, где это возможно, задействовать столь волнующие тебя MMX/SSE


 
Sphinx ©   (2004-02-17 13:54) [73]

Мда, попробовал с Нитями, все отрисовывается лучше некуда, НО!!! время выполнения выросло еще больше!!!
Сделал так: перенес все переменные в RasThread и весь расчет тамже, в конце расчета объявляю:
MainForm.ThEnd:=True;

а в самой MainForm:

while not(ThEnd) do
Application.ProcessMessages;

Ваше мнение?

И еще раз, прошу не преврашать тему во флудовую!!! Я результат хочу получить, а не предупреждение от модераторов!


 
AKul ©   (2004-02-17 14:17) [74]


> Sphinx © (17.02.04 13:54) [73]
> while not(ThEnd) do
> Application.ProcessMessages;


Зачем это? Уберите это! Возвращайте управление основному "выборщику" сообщений.

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


 
Sphinx ©   (2004-02-17 14:26) [75]

> AKul © (17.02.04 14:17) [74]

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


 
Digitman ©   (2004-02-17 14:36) [76]


> скорость работы не увеличивается


скорость работы ЧЕГО ? где код метода Execute ?


 
AKul ©   (2004-02-17 14:36) [77]


> Sphinx © (17.02.04 14:26) [75]
> > AKul © (17.02.04 14:17) [74]
>
> Дело Даже не в этом, если эту строку просто закоментировать,
> то скорость работы не увеличивается

Вы должны не просто ее закоментрировать, а сделать так, чтобы Вы возвращали управление основному "выборщику" сообщений. Т.е., если Вы создайте поток по нажатию кнопки, то Вы должны вернуться из обработчика события нажатия кнопки! В противном случае, увеличить быстродействие не получиться.


> Вот именно этого я понять не могу...код я не менял, просто
> перенес его в нить; поэтому дело наверно всеже не в нем.

У вас в коде было Application.ProcessMessages Вы его убрали (код Вы ж не меняли)???

Код в студию....


 
Юрий Зотов ©   (2004-02-17 14:44) [78]

> Sphinx © (17.02.04 13:54) [73]

То, есть главный поток Вы зациклили на все 100%, а в параллель ему подвесили еще один поток. Чему же удивляться? Ясно, что бедняга процессор даже вздохнуть не успевает.

ThEnd - выкинуть в помойку. Цикл с ProcessMessages - выкинуть туда же. Далее так.

type
TCalcThread = class(TThread)
protected
procedure Execute; override;
public
... // Переменные, необходимые для расчета
end;

TForm1 = class(TForm)
...
procedure FormDestroy(Sender: TObject);
private
FCalcThread: TCalcThread;
procedure Start;
procedure Finish(Sender: TObject)
end;

procedure TCalcThread.Execute;
begin
while not Terminated and (Условие_завершения_расчета) do
begin
... // расчет
end
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if FFCalcThread <> nil then FCalcThread.Terminate;
end;

procedure TForm1.Start;
begin
if FCalcThread <> nil then Exit;
FCalcThread := TCalcThread.Create(True);
with FCalcThread do
begin
OnTerminate := Finish;
... // Настройка исходных данных в FCalcThread
Resume
end
end;

procedure TForm1.Finish(Sender: TObject)
begin
if not (csDestroying in ComponentState) then
with FCalcThread do
begin
... // Обработка результатов расчета
end;
FreeAndNil(FCalcThread)
end;


 
Sphinx ©   (2004-02-17 14:46) [79]

Студия принимайте:
procedure TMainForm.FormActivate(Sender: TObject);
begin
RThread:=RasThread.Create(True);
end;

procedure TMainForm.btStartClick(Sender: TObject);
begin
if not Assigned(ChartingForm) then
ChartingForm:=TChartingForm.Create(Self);

if not Assigned(ProgressForm) then
ProgressForm:=TProgressForm.Create(Self);
ProgressForm.Show;

ThEnd:=False;
RThread.Resume;

while not(ThEnd) do
Application.ProcessMessages;

RThread.Free;
ProgressForm.Hide;
FreeAndNil(ProgressForm);

ChartingForm.ShowModal;
FreeAndNil(ChartingForm);
end;


Далее в Threads:

procedure RasThread.Execute;
begin
{ Place thread code here }
...
Ввод переменных из основной формы
...
Stoping:=False;

repeat
...
Расчет
...
Synchronize(UpDateChart);
Ti:=Ti+dt;
Progrr:=Round((Ti-TBegin)*100/(TEnd-TBegin));
Synchronize(UpDateProgress);
if (Ti-dt)>Tend then Stoping:=True;

until Stoping;

MainForm.ThEnd:=True;
end;

procedure RasThread.UpDateProgress;
begin
ProgressForm.Gauge1.Progress:=Progrr;
end;

procedure RasThread.UpDateChart;
begin
ChartingForm.chXY.SeriesList[0].AddXY(Ti,y);
end;


> Вы должны вернуться из обработчика события нажатия кнопки!

Хм...как видите полностью выйти из обработчика нажатия нельзя, там есть небольшие операции с формами, которые как я понимаю нельзя запихать в Нить (или все же можно???).


 
AKul ©   (2004-02-17 15:03) [80]


> Sphinx © (17.02.04 14:46) [79]
> procedure TMainForm.btStartClick(Sender: TObject);
> begin
> if not Assigned(ChartingForm) then
> ChartingForm:=TChartingForm.Create(Self);
>
> if not Assigned(ProgressForm) then
> ProgressForm:=TProgressForm.Create(Self);
> ProgressForm.Show;
>
> ThEnd:=False;
> RThread.Resume;
>
> while not(ThEnd) do
> Application.ProcessMessages;

На счет цикла с Application.ProcessMessages, думаю, повторять не стоит.

> Хм...как видите полностью выйти из обработчика нажатия нельзя,

Можно!!! Смотрите пост Юрий Зотов © (17.02.04 14:44) [78]
Особое внимание обратите на TForm1.Start и TForm1.Finish.
Юрий Зотов Вам специально в них комментарии написал, чтобы было понятно, что куда вставлять.



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

Текущий архив: 2004.02.29;
Скачать: CL | DM;

Наверх




Память: 0.66 MB
Время: 0.025 c
6-94066
dolphin1
2003-11-28 17:46
2004.02.29
ICQ


1-93932
AkaSaint
2004-02-14 21:19
2004.02.29
Ошибка при приведении объекта к типу предка


1-93905
Wild
2004-02-15 21:00
2004.02.29
Delphi+Flash


1-93999
zamkom
2004-02-16 16:02
2004.02.29
Оптимизация.


3-93786
CAV (Alexander)
2004-02-02 13:36
2004.02.29
Преобразование даты в MS SQL 2000