-
Вношу из Delphi изменения в таблицу SQL-сервера, касающиеся каждой строки, коих более 90000, - процесс занимает около 2-3 минут. Что-бы пользователь не переживал, не зависла ли программа - отображаю ход процесса с помощью ProgressBar. Проблема в том - что после того как начал отображаться данный длительный процесс - если уйти с данного окна на другую Windows-задачу, а потом вернуться (или же просто начать мышью кликать на окне исполняемой программы), то Windows начинает отображать окно работающей пограммы - как зависшее, и ProgressBar - больше не отображает свой ход. Подскажите - как правильно писать код при отображении длительных процессов?
-
> Проблема в том - что после того как начал отображаться данный > длительный процесс - если уйти с данного окна на другую > Windows-задачу, а потом вернуться (или же просто начать > мышью кликать на окне исполняемой программы), то Windows > начинает отображать окно работающей пограммы - как зависшее, > и ProgressBar - больше не отображает свой ход. >
Плохо/неправильно отображаешь. Покажи как.
-
Application.ProcessMessages в цикле
реализовать можно так
If Odd(I) Then Application.ProcessMessages
где I - счетчик цикла или другая переменная - что там используется?
-
> коих более 90000, - процесс занимает около 2-3 минут. посмотрел тут, апдейт 171832 записей (увеличение цены товара на 10%) занимает 4.181(первая проверка)/3.250(вторая) сек. 90000 должно и того меньше... прогресс не нужен, если запрос оптимизировать.
-
> Application.ProcessMessages использование в длинных циклах "притормозит" программу еще больше.
-
Screen.Cursor := crSQLWait;
try
Execute 90000 raz
finally
Screen.Cursor := crDefault;
end;
-
>использование в длинных циклах "притормозит" программу еще больше.
Ну это как делать, можно вообще делать проверку на прибавление счетчика на 1000 и особых задержек выполнения не будит, но и интерфейс не подвиснет.
-
-
Большое спасибо всем, кто откликнулся помочь!..
И всё же именно мой вопрос остался без ответа, наверное я не сумел его донести. Меня интересует именно то обстоятельство, что Windows обозначает мою программу во время длительного процесса как зависшую, и если кто знает - пожалуйста подскажите, как именно этого избежать.
Всё остальное, что на эту тему подсказали, я уже применяю: увеличиваю шаг перерисовки ProgressBar, отображаю перед операцией курсор как crSQLWait, подсказки же, что апдейт 172 тысяч записей занимает 4 секунды - наверное это просто на другой SQL базе и на другой технике такие скорости.
У меня Delphi обращается к базе Firebird через компоненты FIBPlus. И SQL-команда: UPDATE <имя таблицы> SET <имя целочисленного поля> = 0 - идёт на 90000 записей примерно 10 секунд на машине с частотой 2,5 Ггц.
Поэтому, когда идёшь по всей таблице, и для каждой записи делаешь какие-то нетривиальные вычисления, перед тем как обновить данные - это требует время. Пусть не 2-3 минуты, но даже минута - этого уже хватает для того неприятного обстоятельства, о котором я упоминал: при переключении в другую задачу и возвращении - программа НЕ виснет, но перестаёт отображать процесс!
А вопрос Германна: > Плохо/неправильно отображаешь. > Покажи как. честно говоря немного не понял..
while not Eof do {опрации над текущей записью} ProgressBar.Position := ...; Next; end; А как ещё можно отображать ??
-
> что Windows обозначает мою программу во время длительного процесса как зависшую, и если кто знает - пожалуйста подскажите, как именно этого избежать. сказали во 2 и 7 постах.
> 10 секунд на машине с частотой 2,5 Ггц. ... я проверял на 2Ггц. ХП 32 разрядная, база mdb (Access)
> делаешь какие-то нетривиальные вычисления вычисления, даже самые нетривиальные обычно занимают где то десятое место после неправильной работы с компонентами/базой.
-
> [8] Anthony © (29.12.10 17:55) > А как ещё можно отображать ??
А где > [2] WRWRWR (29.12.10 05:59) > Application.ProcessMessages в цикле
Не на каждой итерации или где > [7] 12 © (29.12.10 12:17) > http://pda.delphimaster.net/?id=1282149795&n=3
А говоришь всё пробовал. Ну и это > [8] Anthony © (29.12.10 17:55) > UPDATE <имя таблицы> SET <имя целочисленного поля> = 0
от техники зависит, только не железа а программирования. Параметры надо.
-
Спасибо!! Использование Application.ProcessMessages помогло, я умудрился не увидеть эту подсказку сразу... Кстати, давая ссылку > http://pda.delphimaster.net/?id=1282149795&n=3мне подсказывали почитать про многопоточность?.. Я пробовал - ссылка на эту книгу к сожалению не работает И ещё: хотелось бы знать что Inovet © имел ввиду, написав: > от техники зависит, только не железа а программирования. Параметры надо. Я же упомянул простой SQL оператор, обнуляющий всего одно целочисленное поле в таблице с 90тыс.записями. А какие ещё "параметры надо"? Разве такой код можно написать, чтобы он работал быстрее? Или Вы имели ввиду какие-то опции компоненты, производящей SQL запрос? Или величину (вес) каждой записи в таблице БД ? Поясните, если можно...
-
Спасибо!! Использование Application.ProcessMessages помогло, я умудрился не увидеть эту подсказку сразу... Кстати, давая ссылку > http://pda.delphimaster.net/?id=1282149795&n=3мне подсказывали почитать про многопоточность?.. Я пробовал - ссылка на эту книгу к сожалению не работает И ещё: хотелось бы знать что Inovet © имел ввиду, написав: > от техники зависит, только не железа а программирования. Параметры надо. Я же упомянул простой SQL оператор, обнуляющий всего одно целочисленное поле в таблице с 90тыс.записями. А какие ещё "параметры надо"? Разве такой код можно написать, чтобы он работал быстрее? Или Вы имели ввиду какие-то опции компоненты, производящей SQL запрос? Или величину (вес) каждой записи в таблице БД ? Поясните, если можно...
-
> Я пробовал - ссылка на > эту книгу к сожалению не работает
Там в [23] написано как пользоваться этой ссылкой.
-
> ссылка на эту книгу к сожалению не работает а так? http://podgoretsky.com/ftp/Docs/Delphi/DX/Martin%20Harvey%20-%20Threads.pdfне получится - зайди на сайт найди там. > Разве такой код можно написать, чтобы он работал быстрее? выигрыш на 1-ой команде будет мало заметен. параметры и все остальное заметны когда много запросов в цикле. хотя, ставишь (если в фибах подобное есть) асинхронный режим команде, без ожидания результата, и будет вид что выполнилось в 1 мсек. подойдет только если клиенту пофиг на результат команды (в смысле а выполнилась ли она вообще там на сервере).
-
Ссылка на pdf файл работает, спасибо!
> выигрыш на 1-ой команде будет мало заметен
- а я имел ввиду всего 1 команду, удивившись, что у кого-то UPDATE выполняется за 3-4 секунды на 172тыс.записей!
И SQL база у меня локальная, поэтому обманывать пользователя аснихронным режимом не получится)
Большое спасибо всем за помощь!
-
> Anthony (29.12.2010 19:05:11) [11]
Пробуй еще.
-
> Anthony © (29.12.10 19:39) [15]
Без твоего кода, только абстракция.
-
> [11] Anthony © (29.12.10 19:05) > И ещё: хотелось бы знать что Inovet © имел ввиду, написав: > > > от техники зависит, только не железа а программирования. Параметры надо.
По постам у тебя получается цикл на 90000 итераций в котором, "для каждой записи делаешь какие-то нетривиальные вычисления" и выполняешь запрос на обновление для каждой, а в приведённом запросе не видно параметров, а их бы здесь самое место применить, будет быстрее и правильнее. Но теперь ты говоришь
> [12] Anthony © (29.12.10 19:22) > простой SQL оператор, обнуляющий всего одно целочисленное поле в таблице с 90тыс.записями
что собственно и показано в
> [8] Anthony © (29.12.10 17:55) > UPDATE <имя таблицы> SET <имя целочисленного поля> = 0
обнуляется поле во всех записях. Тогда каой цикл и откуда тормоза?
И что там с индексами у тебя? хоть для этого запроса они не нужны. Или есть таки в запросе WHERE?
-
> > [12] Anthony © (29.12.10 19:22) > > простой SQL оператор, обнуляющий всего одно целочисленное > поле в таблице с 90тыс.записями > > что собственно и показано в > > > [8] Anthony © (29.12.10 17:55) > > UPDATE <имя таблицы> SET <имя целочисленного поля> = 0 > > обнуляется поле во всех записях. Тогда каой цикл и откуда > тормоза? >
И более того. Непонятно чем в данном случае мог помочь ProcessMessages?
-
А почему ни кто не сказал мальчику до сих пор, что ttable must die?
-
> А почему ни кто не сказал мальчику до сих пор, что ttable > must die?
"мальчику" 40 лет, знает, поди..
-
> А почему ни кто не сказал мальчику до сих пор, что ttable > must die?
А шде ты TTable увидел?
-
> while not Eof do > {опрации над текущей записью} > ProgressBar.Position := ...; > Next; > end; > А как ещё можно отображать ??
ИМХО "Ошибка" здесь.
-
все > while not Eof do > > Next; > end; засунуть в поток
где то написать > while not Eof do > if УСЛОВИЕ then SendMessge(твоему окну процент сделанного в lParam) > Next; > end;
Твое окно по этому мессаджу передвигает ProgressBar.Position В остальное время курит - никакого зависание
Книга была посоветована не случайно, там почти такой же пример рассматривается. Немного переделать только.
-
> 12 © (30.12.10 09:21) [24]
ЗЛО советуешь :)
-
> > while not Eof do > > > > Next; > > end;
тут если , то не глядел, наверное и ЗЛО. Но тут уже другие посоветовали как лучше
Смысл сказанного: из потока при длительных операциях основному окну сообщать ход выполнения, только это.
-
... дробь крупновата. ИМХО SQL спасет отца русской демократии.
-
> А шде ты TTable увидел?
Я код увидел, этого достаточно. Там кроме ттабле или тквери в режиме ттабле ничего не подходит.
-
Не, конечно, написать вместо этого хранимую процедуру будет намного продуктивнее :-Р
-
> [29] Cobalt © (31.12.10 12:48) > написать вместо этого хранимую процедуру будет намного продуктивнее
Не всё сразу, сначала с параметрами разобраться.
|