Текущий архив: 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