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

Вниз

Как правильно отображать ход долгих процессов?   Найти похожие ветки 

 
Anthony ©   (2010-12-29 01:30) [0]

Вношу из Delphi изменения в таблицу SQL-сервера, касающиеся каждой строки, коих более 90000, - процесс занимает около 2-3 минут.
Что-бы пользователь не переживал, не зависла ли программа -
отображаю ход процесса с помощью ProgressBar.
Проблема в том - что после того как начал отображаться данный длительный процесс - если уйти с данного окна на другую Windows-задачу, а потом вернуться (или же просто начать мышью кликать на окне исполняемой программы), то Windows начинает отображать окно работающей пограммы - как зависшее, и ProgressBar - больше не отображает свой ход.
Подскажите - как правильно писать код при отображении длительных процессов?


 
Германн ©   (2010-12-29 02:10) [1]


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

Плохо/неправильно отображаешь.
Покажи как.


 
WRWRWR   (2010-12-29 05:59) [2]

Application.ProcessMessages в цикле

реализовать можно так

If Odd(I) Then Application.ProcessMessages

где I - счетчик цикла или другая переменная - что там используется?


 
sniknik ©   (2010-12-29 07:53) [3]

> коих более 90000, - процесс занимает около 2-3 минут.
посмотрел тут, апдейт 171832 записей (увеличение цены товара на 10%) занимает 4.181(первая проверка)/3.250(вторая) сек. 90000 должно и того меньше... прогресс не нужен, если запрос оптимизировать.


 
sniknik ©   (2010-12-29 07:55) [4]

> Application.ProcessMessages
использование в длинных циклах "притормозит" программу еще больше.


 
Ega23 ©   (2010-12-29 08:10) [5]

Screen.Cursor := crSQLWait;
try
 Execute 90000 raz
finally
 Screen.Cursor := crDefault;
end;


 
WRWRWR   (2010-12-29 08:11) [6]

>использование в длинных циклах "притормозит" программу еще больше.

Ну это как делать, можно вообще делать проверку на прибавление счетчика на 1000 и особых задержек выполнения не будит, но и интерфейс не подвиснет.


 
12 ©   (2010-12-29 12:17) [7]

http://delphimaster.net/view/15-1282149795/


 
Anthony ©   (2010-12-29 17:55) [8]

Большое спасибо всем, кто откликнулся помочь!..

И всё же именно мой вопрос остался без ответа, наверное я не сумел его донести. Меня интересует именно то обстоятельство, что 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;
А как ещё можно отображать ??


 
sniknik ©   (2010-12-29 18:04) [9]

> что Windows обозначает мою программу во время длительного процесса как зависшую, и если кто знает - пожалуйста подскажите, как именно этого избежать.
сказали во 2 и 7 постах.

> 10 секунд на машине с частотой 2,5 Ггц.
... я проверял на 2Ггц. ХП 32 разрядная, база mdb (Access)

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


 
Inovet ©   (2010-12-29 18:07) [10]

> [8] Anthony ©   (29.12.10 17:55)
> А как ещё можно отображать ??

А где

> [2] WRWRWR   (29.12.10 05:59)
> Application.ProcessMessages в цикле

Не на каждой итерации
или где

> [7] 12 ©   (29.12.10 12:17)
> http://delphimaster.net/view/15-1282149795/

А говоришь всё пробовал.

Ну и это

> [8] Anthony ©   (29.12.10 17:55)
> UPDATE <имя таблицы> SET <имя целочисленного поля> = 0

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


 
Anthony ©   (2010-12-29 19:05) [11]

Спасибо!!
Использование Application.ProcessMessages помогло, я умудрился не увидеть эту подсказку сразу...

Кстати, давая ссылку
> http://delphimaster.net/view/15-1282149795/
мне подсказывали почитать про многопоточность?.. Я пробовал - ссылка на
эту книгу к сожалению не работает

И ещё: хотелось бы знать что Inovet © имел ввиду, написав:
> от техники зависит, только не железа а программирования. Параметры надо.

Я же упомянул простой SQL оператор, обнуляющий всего одно целочисленное поле в таблице с 90тыс.записями. А какие ещё "параметры надо"?
Разве такой код можно написать, чтобы он работал быстрее?
Или Вы имели ввиду какие-то опции компоненты, производящей SQL запрос?
Или величину (вес) каждой записи в таблице БД ?
Поясните, если можно...


 
Anthony ©   (2010-12-29 19:22) [12]

Спасибо!!
Использование Application.ProcessMessages помогло, я умудрился не увидеть эту подсказку сразу...

Кстати, давая ссылку
> http://delphimaster.net/view/15-1282149795/
мне подсказывали почитать про многопоточность?.. Я пробовал - ссылка на
эту книгу к сожалению не работает

И ещё: хотелось бы знать что Inovet © имел ввиду, написав:
> от техники зависит, только не железа а программирования. Параметры надо.

Я же упомянул простой SQL оператор, обнуляющий всего одно целочисленное поле в таблице с 90тыс.записями. А какие ещё "параметры надо"?
Разве такой код можно написать, чтобы он работал быстрее?
Или Вы имели ввиду какие-то опции компоненты, производящей SQL запрос?
Или величину (вес) каждой записи в таблице БД ?
Поясните, если можно...


 
Германн ©   (2010-12-29 19:24) [13]


> Я пробовал - ссылка на
> эту книгу к сожалению не работает

Там в [23] написано как пользоваться этой ссылкой.


 
sniknik ©   (2010-12-29 19:27) [14]

> ссылка на эту книгу к сожалению не работает
а так?
http://podgoretsky.com/ftp/Docs/Delphi/DX/Martin%20Harvey%20-%20Threads.pdf
не получится - зайди на сайт найди там.

> Разве такой код можно написать, чтобы он работал быстрее?
выигрыш на 1-ой команде будет мало заметен. параметры и все остальное заметны когда много запросов в цикле.

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


 
Anthony ©   (2010-12-29 19:39) [15]

Ссылка на pdf файл работает, спасибо!

> выигрыш на 1-ой команде будет мало заметен

- а я имел ввиду всего 1 команду, удивившись, что у кого-то UPDATE выполняется за 3-4 секунды на 172тыс.записей!

И SQL база у меня локальная, поэтому обманывать пользователя аснихронным режимом не получится)

Большое спасибо всем за помощь!


 
Anatoly Podgoretsky ©   (2010-12-29 19:49) [16]

> Anthony  (29.12.2010 19:05:11)  [11]

Пробуй еще.


 
Anatoly Podgoretsky ©   (2010-12-29 20:00) [17]


> Anthony ©   (29.12.10 19:39) [15]

Без твоего кода, только абстракция.


 
Inovet ©   (2010-12-29 23:54) [18]

> [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?


 
Германн ©   (2010-12-30 01:51) [19]


> > [12] Anthony ©   (29.12.10 19:22)
> > простой SQL оператор, обнуляющий всего одно целочисленное
> поле в таблице с 90тыс.записями
>
> что собственно и показано в
>
> > [8] Anthony ©   (29.12.10 17:55)
> > UPDATE <имя таблицы> SET <имя целочисленного поля> = 0
>
> обнуляется поле во всех записях. Тогда каой цикл и откуда
> тормоза?
>

И более того. Непонятно чем в данном случае мог помочь ProcessMessages?


 
Плохиш ©   (2010-12-30 03:30) [20]

А почему ни кто не сказал мальчику до сих пор, что ttable must die?


 
MonoLife ©   (2010-12-30 03:57) [21]


> А почему ни кто не сказал мальчику до сих пор, что ttable
> must die?

"мальчику" 40 лет, знает, поди..


 
Ega23 ©   (2010-12-30 08:36) [22]


> А почему ни кто не сказал мальчику до сих пор, что ttable
> must die?

А шде ты TTable увидел?


 
Dennis I. Komarov ©   (2010-12-30 09:07) [23]


> while not Eof do
>  {опрации над текущей записью}
>  ProgressBar.Position := ...;
>  Next;
> end;
> А как ещё можно отображать ??

ИМХО "Ошибка" здесь.


 
12 ©   (2010-12-30 09:21) [24]

все
> while not Eof do
>
>  Next;
> end;
засунуть в поток

где то написать
> while not Eof do
>
if УСЛОВИЕ then SendMessge(твоему окну процент сделанного в lParam)
>  Next;
> end;

Твое окно по этому мессаджу передвигает ProgressBar.Position
В остальное время курит - никакого зависание

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


 
Dennis I. Komarov ©   (2010-12-30 09:47) [25]


> 12 ©   (30.12.10 09:21) [24]

ЗЛО советуешь :)


 
12 ©   (2010-12-30 09:52) [26]


> > while not Eof do
> >
> >  Next;
> > end;

тут если , то не глядел, наверное и ЗЛО.
Но тут уже другие посоветовали как лучше

Смысл сказанного:
из потока при длительных операциях основному окну сообщать ход выполнения, только это.


 
Dennis I. Komarov ©   (2010-12-30 09:57) [27]

... дробь крупновата. ИМХО SQL спасет отца русской демократии.


 
Плохиш ©   (2010-12-30 15:22) [28]


> А шде ты TTable увидел?

Я код увидел, этого достаточно. Там кроме ттабле или тквери в режиме ттабле ничего не подходит.


 
Cobalt ©   (2010-12-31 12:48) [29]

Не, конечно, написать вместо этого хранимую процедуру будет намного продуктивнее :-Р


 
Inovet ©   (2010-12-31 13:22) [30]

> [29] Cobalt ©   (31.12.10 12:48)
> написать вместо этого хранимую процедуру будет намного продуктивнее

Не всё сразу, сначала с параметрами разобраться.



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

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

Наверх




Память: 0.55 MB
Время: 0.013 c
4-1246600171
БарЛог
2009-07-03 09:49
2011.03.27
Функция NetGetDCName библиотеки netapi32.dll


2-1293272162
tanyusha333
2010-12-25 13:16
2011.03.27
Не могу решить задачу по системному программированию!


2-1294043991
black-jack
2011-01-03 11:39
2011.03.27
Http post


2-1293463778
Mitroshin
2010-12-27 18:29
2011.03.27
Возможно ли использовать строку STFilter в TDBGridEh как Edit-ы?


2-1294129298
cross
2011-01-04 11:21
2011.03.27
освобождение памяти под интерфейс