powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Как избежать зависания приложения ?
23 сообщений из 23, страница 1 из 1
Как избежать зависания приложения ?
    #35934263
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте ! Помогите решить проблему:
Есть ДВ в котором отображается более 20000 записей. У каждой записи есть поле active типа чекбокса, которое пользователь устанавливает/снимает, потом кликает на кнопку, на которой такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
for i= 1  to dw_list.rowcount()
 if dw_list.object.active[i]= 1  then
	dirh=dw_list.object.dirhouse[i];
	no_acc=dw_list.object.no_account[i];
	c_d=dw_list.object.current_date[i];
	sum=dw_list.object.sum[i]-dw_list.object.sumopl[i];
	countt=dw_list.object.countt[i];
	code=dw_list.object.code[i];
  insert into flat.reestrdolg(dirhouse,no_account,current_date,sum,countt,typedoc,code)
  values(:dirh,:no_acc,:c_d,:sum,:countt, 2 ,:code);
end if;
next;
commit;
После клика на кнопке приложение зависает пока работает цикл по записям ДВ...
Есть ли в PB аналог дельфийской функции ProcessMessage ?
Заранее спасибо за помощь.
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35934290
Dim2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lioner пишет:

> После клика на кнопке приложение зависает пока работает цикл по записям
> ДВ...

Ну и чёрт с ним.

> Есть ли в PB аналог дельфийской функции ProcessMessage ?

Yield(). Приятной борьбы с нажатиями кнопок в процессе .
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35934321
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dim2000
lioner пишет:

> После клика на кнопке приложение зависает пока работает цикл по записям
> ДВ...

Ну и чёрт с ним.

> Есть ли в PB аналог дельфийской функции ProcessMessage ?

Yield(). Приятной борьбы с нажатиями кнопок в процессе .

Спасибо, помогло. Приложение уже не висит,но хотелось бы блокировать само окно в котором в цикле обрабатываются записи ДВ и сделать курсор мышки в виде песочных часов, но только в пределах клиентской области этого окна. Возможно такое ?
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35934405
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lionerЗдравствуйте ! Помогите решить проблему:
Есть ДВ в котором отображается более 20000 записей. У каждой записи есть поле active типа чекбокса, которое пользователь устанавливает/снимает, потом кликает на кнопку, на которой такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
for i= 1  to dw_list.rowcount()
 if dw_list.object.active[i]= 1  then
	dirh=dw_list.object.dirhouse[i];
	no_acc=dw_list.object.no_account[i];
	c_d=dw_list.object.current_date[i];
	sum=dw_list.object.sum[i]-dw_list.object.sumopl[i];
	countt=dw_list.object.countt[i];
	code=dw_list.object.code[i];
  insert into flat.reestrdolg(dirhouse,no_account,current_date,sum,countt,typedoc,code)
  values(:dirh,:no_acc,:c_d,:sum,:countt, 2 ,:code);
end if;
next;
commit;
После клика на кнопке приложение зависает пока работает цикл по записям ДВ...
Есть ли в PB аналог дельфийской функции ProcessMessage ?
Заранее спасибо за помощь.
1. Надо УБРАТЬ идиотизм в виде embedded SQL ( insert into flat.reestrdolg ), и вместо этого просто собирать insertы в датастор.
2. Цикл нужно писать ЗАРАНЕЕ определив dw_list.rowcount(), он что у вас, меняется в процессе цикла?
3. Цикл нужно писать не на ВСЕ ряды, а через FIND на active =1
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35934594
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Филипп +1
Абсолютно согласен
-----------------------------------------------------------------------------
Главная деталь любой машины - голова ее владельца
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35934672
Фотография Dmitry.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а если религия позволяет использовать хранимые процедуры,
то в ДВ update properties можно указать хранимку
параметрами которой могут быть даже computed fields
тогда скрипт сводится к:

dw_list.update()
commit;
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935121
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Филипп1. Надо УБРАТЬ идиотизм в виде embedded SQL ( insert into flat.reestrdolg ), и вместо этого просто собирать insertы в датастор.
2. Цикл нужно писать ЗАРАНЕЕ определив dw_list.rowcount(), он что у вас, меняется в процессе цикла?
3. Цикл нужно писать не на ВСЕ ряды, а через FIND на active =1

1. Как собирать insertы в датастор ? Можно пример кода ?
С учетом ваших пунктов 2 и 3, упростил цикл так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
c_d=dw_data.object.d1_ins[ 1 ];
typedoc=integer(dw_data.object.typedoc_ins[ 1 ]);
dw_list.setfilter("active=1");
dw_list.filter();
rcount=dw_list.rowcount();
for i= 1  to rcount
 id=dw_list.object.id[i];
 sum=dw_list.object.sum[i]-dw_list.object.sumopl[i];
 insert into flat.reestrdolg(dirhouse,no_account,current_date,sum,countt,typedoc,code)
 select dirhouse,no_account,:c_d,:sum,countt,:typedoc,code
 from flat.reestrdolg
 where id=:id;
next;
commit;
dw_list.setfilter("");
dw_list.filter();
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935172
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lioner,
Вот этот кусок:
Код: plaintext
1.
2.
3.
 insert into flat.reestrdolg(dirhouse,no_account,current_date,sum,countt,typedoc,code)
 select dirhouse,no_account,:c_d,:sum,countt,:typedoc,code
 from flat.reestrdolg
 where id=:id;
лучше запихивать в DataStore, а потом делать Update на всю DataStore целиком:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
DataStore lds
lds = CREATE DataStore
lds.DataObject = 'ds_reestrdolg'
lds.SetTransObject(sqlca)

// В цикле:
lds.InsertRow(li_i)
lds.SetItem(li_i, 'dirhous', dirh)
...

//После выхода из цикла:
lds.Update()
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935182
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Riska,

Поправка:
Не lds.InsertRow(li_i), a
Код: plaintext
li_i = lds.InsertRow( 0 )
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935229
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Riskalioner,
Вот этот кусок:
Код: plaintext
1.
2.
3.
 insert into flat.reestrdolg(dirhouse,no_account,current_date,sum,countt,typedoc,code)
 select dirhouse,no_account,:c_d,:sum,countt,:typedoc,code
 from flat.reestrdolg
 where id=:id;
лучше запихивать в DataStore, а потом делать Update на всю DataStore целиком:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
DataStore lds
lds = CREATE DataStore
lds.DataObject = 'ds_reestrdolg'
lds.SetTransObject(sqlca)

// В цикле:
lds.InsertRow(li_i)
lds.SetItem(li_i, 'dirhous', dirh)
...

//После выхода из цикла:
lds.Update()

По вашему совету сделал так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
c_d=dw_data.object.d1_ins[ 1 ];
typedoc=integer(dw_data.object.typedoc_ins[ 1 ]);
dw_list.setfilter("active=1");
dw_list.filter();
rcount=dw_list.rowcount();
ds=create datastore;
sql="select id,dirhouse,no_account,current_date,sum,countt,typedoc,code,dateizm from flat.reestrdolg where id=1";
new_syntax=SQLCA.SyntaxFromSQL(sql,'Style(Type=Grid)',error_syntaxfromSQL);
ds.create(new_syntax,sqlerror);
ds.settransobject(sqlca);
ds.retrieve();
for i= 1  to rcount
  sum=dw_list.object.sum[i]-dw_list.object.sumopl[i];
  row=ds.insertrow( 0 );
  ds.object.dirhouse[row]=dw_list.object.dirhouse[i];
  ds.object.no_account[row]=dw_list.object.no_account[i];
  ds.object.current_date[row]=c_d;
  ds.object.sum[row]=sum;
  ds.object.countt[row]=dw_list.object.countt[i];
  ds.object.typedoc[row]=typedoc;
  ds.object.code[row]=dw_list.object.code[i];
next;
ds.accepttext();
ds.update();
commit;
dw_list.setfilter("");
dw_list.filter();
Все равно цикл выполняется 2 минуты...
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935238
Фотография Raven A
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все строго IMHO.
Если изменения чекбокса приводят к изменению статуса записи в DW,
то, на мой взгляд, прав Dmitry.

Напишите хранимку и поставте ее в Stored Procedure Update.
Если это "религия" не позволяет, перекройте event SQLPreView(...),
напишите там все, что Вам надо.

В результате все сведется к тривиальному li_Res = DW.Update()
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935247
Фотография Raven A
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В догонку.
Если требуется скорость, не используйте дот нотацию для доступа к значениям полей.
Используйте DW.GetXXXXX(), будет быстрее.
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935635
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решил проверить скорость простого апдейта:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
dw_list.setfilter("active=1");
dw_list.filter();
rcount=dw_list.rowcount();
for i= 1  to rcount
 dw_list.object.typedoc[i]= 2 ;
next;
dw_list.update();
commit;
dw_list.setfilter("");
dw_list.filter();
Время почти 2 минуты...
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935672
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так может база тормозит?

-----------------------------------------------------------------------------
Главная деталь любой машины - голова ее владельца
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935700
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
spas2001Так может база тормозит?
Перегрузил комп, перезапустил сервак, все равно 2 минуты...
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35935890
lioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тут вот еще какое дело. dw_list содержит такой запрос (устанавливает поле active в 1):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select a.owne,r.sum,r.no_account,r.countt,h.gek,
 (select (type_street_name+' '+s.name) from  ref.street rs,dba.streets s
 where rs.id=h.street and rs.id=s.ref_code) streetnm,
 string(streetnm,', д. ',isnull(h.num, 0 ),isnull(h.num2,''),' ,кв. ',a.no_flat) dname,r.id,r.current_date,s.fio,
 isnull((select sum(sum) from flat.doc din,flat.account ain
  where ain.id=din.account and ain.dirhouse=a.dirhouse and ain.no_account=a.no_account
	and din.in_out=- 1  and din.current_date>=r.current_date and din.current_date<
	isnull((
	 select min(current_date) from flat.reestrdolg
	 where dirhouse=r.dirhouse and no_account=r.no_account and current_date>r.current_date
	),ymd( 3000 , 01 , 01 ))
 ), 0 ) sumopl,
 (if sumopl= 0  then  1  else  0  endif) active,r.code,r.dirhouse,r.typedoc,r.dateizm
 from dba.house h,flat.reestrdolg r,flat.account a,dba.sotrud s
 where a.dirhouse=r.dirhouse and a.no_account=r.no_account and a.dirhouse=h.id
 and r.code=s.id and a.copy is null
 and r.current_date between ctod(:d1) and ctod(:d2) and r.typedoc=:typedoc
 order by r.current_date,h.gek,a.no_account
Ретрив dw_list-а отрабатывает за 2-3 секунды. Если прописать перед селектом инсерт в эту же таблицу, то такая вставка сработает быстро (быстрее 2 минут при цикле). Но после этого нужно как-то обработать те записи, в которых пользователь САМ изменил поле active.
Как добраться из всех 30000 записей ДВ к тем записям, в которых пользователь САМ изменил поле active?
Тогда можно было бы :
1) insert ... select (быстро отработает)
2) удаление из таблицы тех записей, в которых пользователь САМ изменил поле active
3) вставка в таблицу тех записей, в которых пользователь САМ изменил поле active
Сам dw_list не обновляем, пользователь может редактировать только поле active.
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35937047
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lionerТут вот еще какое дело. dw_list содержит такой запрос (устанавливает поле active в 1):
Как добраться из всех 30000 записей ДВ к тем записям, в которых пользователь САМ изменил поле active?
Написать цикл на GetNextModified
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35937062
PBСпец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>>После клика на кнопке приложение зависает пока работает цикл по записям ДВ...
Я думаю, в вашем случае может помочь SharedObjects и PBNI. При помощи SharedObjects можно сделать несколько потоков и, соответственно, писать в базу из нескольких потоков. Будет быстрее.
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35937081
PBСпец
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ФилиппНаписать цикл на GetNextModified
Не думаю, что с GetNextModified станет быстрее, ведь в самой функции идет тот же самый цикл линейного поиска измененной записи.
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35937179
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PBСпецФилиппНаписать цикл на GetNextModified
Не думаю, что с GetNextModified станет быстрее, ведь в самой функции идет тот же самый цикл линейного поиска измененной записи.
Чушь собачья, читайте внимательнее постановку задачи...
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35937686
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Embedded SQL и DataStore работают примерно также грустно по скорости на большом количестве строк.
Чтобы ускориться склеивайте insert'ы ручками (например штук по 100) и запускайти их через EXECUTE IMMEDIATE. Зависит от базы, например для MS SQL скорость возрастает в десятки раз.
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35938426
Igor Domnith
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
lioner
Как добраться из всех 30000 записей ДВ к тем записям, в которых пользователь САМ изменил поле active?

Формировать самому массив измененных строк в itemchanged
а затем обрабатывать только строки из этого массива, очищая его после Update().
...
Рейтинг: 0 / 0
Как избежать зависания приложения ?
    #35938728
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Domnithlioner
Как добраться из всех 30000 записей ДВ к тем записям, в которых пользователь САМ изменил поле active?

Формировать самому массив измененных строк в itemchanged
а затем обрабатывать только строки из этого массива, очищая его после Update().
Надо делать как Филипп написал, через GetNextModified.
А чтобы эта ф-я показывала только то что изменил сам юзер, надо после программного заполнения перед отдачей юзеру на редактирование вызвать ResetUpdate(), который сбросит флаги изменения.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Как избежать зависания приложения ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]