Текущий архив: 2006.04.02;
Скачать: CL | DM;
Вниз"долгая" ADOStoredProc Найти похожие ветки
← →
tyo (2006-03-10 20:30) [0]Запускаю с клиента через ExecProc серверную процедуру, к-рая работает довольно долго (неск. мин). При этом если юзер, соскучившись, уходит в какое-нить другое приложение, то переключиться обратно он не может пока мой ExecProc не доработает до конца. Хотелось бы:
1. Чтобы можно переключиться обратно и до завершения.
2. Чтобы если на момент окончания ExecProc юзер будет нах. в др. приложении, моя прога как-то автоматически ему сигнализировала (например помигала бы в виндовом статус-баре)
Как бы это сделать?
← →
Desdechado © (2006-03-10 20:33) [1]запускать в отдельном потоке
← →
tyo (2006-03-10 20:39) [2]И по окончании Thread"а снова насильно активизировать осн. окно проги?
← →
Жуков Олег (2006-03-10 20:46) [3]> (например помигала бы в виндовом статус-баре)
FlashWindow(Application.Handle, ..)
← →
tyo (2006-03-11 10:56) [4]Thread не помогает
Если как-то так:
with ProgressBarThead.Create(FALSE) do onTerminate:=NIL;
with StoreProcThead.Create(FALSE) do onTerminate:=ShowResult;
то сначала полностью выполняется хранимая процедура, к-рая вызывается из StoreProcThread (в этот момент вся прога "мертвая"), а уж потом начинает ползать ProgressBar.
Что-то не так я делаю?
← →
sniknik © (2006-03-11 11:52) [5]> Что-то не так я делаю?
первое поток. судя по всему выполняемая часть работает в основном. приведенный "код" этой части не содержит.
а время выполнения запроса сервером "разложить" на составляющие (для ProgressBar) нельзя, если только в самой процедуре не делать вызовов чегото что будет слать сообщения с процентом выполнения (этого никто не делает, т.к. кроме замороченности еще и затормозиш обработку на порядки (была минута станет 10 или даже 100), и смысл тогда?).
второе процедуру. проверь в QA выполнение процедуры занимает те же несколько мин? (без смысла действий и структуры/индексов трудно чтото сказать... но догадываюсь, что время работы неоправдано большое изза неправильностей в написании. основное в догадке - тот кто может написать оптимальную процедуру на несколько мин тот вряд ли будет задавать вопросы уровня начинающих)
третье вызов. использовать ADOStoredProc уже неправильно (очень очень маленькая в этом погрешность, но всетаки), возьми вместо него ADODataSet и почитай про асинхронную обработку запросов. (просто по методам пробегись все что встретится про то и читай) поток не понадобится вообще.
← →
tyo (2006-03-13 14:48) [6]>судя по всему выполняемая часть работает в основном.
Выполняемая часть :
Unit ThreadProc;
type
TStoredProcThread=class(TThread)
.........
TStoredProcThread.Execute;
begin
MainForm.ADOStoredProc1.ExecProc;
end;
вызывается из MainForm как TStoredProcThread.Create(FALSE)...
>проверь в QA выполнение процедуры занимает те же несколько мин?
Ессно столько же. Оракловая процедура, бегает по здоровенной базе сделок, формирует прогнозный портфель ценных бумаг.
>ADODataSet и почитай про асинхронную обработку запросов. (просто по методам пробегись все что встретится про то и читай) поток не понадобится вообще.
А при запуске с eoAsyncExecute я ж не узнаю, когда хранимая процедура закончит работу?
← →
sniknik © (2006-03-13 16:22) [7]> Выполняемая часть :
> ...
естественно, обращатся к обьектам VCL из потока без синхронизации нельзя. удивительно как это еще не глючит.
> бегает по здоровенной базе сделок, формирует прогнозный портфель ценных бумаг.
с индексами, оптимизацией... т.д., там етественно все в порядке? процедуру кто писал?
> я ж не узнаю, когда хранимая процедура закончит работу?
событие есть у коннекта, посмотри.
← →
tyo (2006-03-17 14:07) [8]> естественно, обращатся к обьектам VCL из потока без синхронизации
> нельзя. удивительно как это еще не глючит
Не, канешна с синхронизацией, эт я так изложил чересчур схематично.
Сделал так: запускаю свою StoredProc в трейде через ADOCommand с опцией eoAsyncExecute, а в другом трейде опрашиваю StoredProc.States, пока последний не перестанет быть stExecuting
Все отлично, единственное что -- как бы мне "поймать" на клиенте возможные ошибки при выполнении оракловой процедуры?
Обычно делал что-то типа
try ExecProc; except ShowMessage("Error in StoredProc!");end;
А здесь? StoreProc отработала, флажок stExecuting упал, а результат неизвестен...
← →
tyo (2006-03-17 14:26) [9]Все, понял. Вот где ее можно поймать, для уже запущенной ранее асинхронно процедуры:
procedure Update
var
OS:TObjectStates
begin
.........
repeat
try
OS:=StoredProc.States;
except
ShowMessage("Error in Proc!");
end;
until not (stExecuting in OS);
end;
← →
sniknik © (2006-03-17 14:54) [10]> Не, канешна с синхронизацией, эт я так изложил чересчур схематично.
тогда зачем поток? все что в синхронизации выполняется в основном.
> через ADOCommand с опцией eoAsyncExecute,
а это открывает третий внутренний который тоже "обессмысливает" твой дополнительний.
> а в другом трейде опрашиваю StoredProc.States, пока последний не перестанет быть stExecuting
событе значит не подошло? а ведь там же и возвращаемые ошибки можно посмотреть.
> Все, понял. Вот где ее можно поймать, для уже запущенной ранее асинхронно процедуры:
нет, это только ошибка присвоения OS:=StoredProc.States; ловится, то что в другом потоке происходит (от eoAsyncExecute) так не поймаеш.
← →
tyo (2006-03-17 16:18) [11]> а это открывает третий внутренний который тоже "обессмысливает" твой дополнительний.
Ваша правда. Оказалось достаточно асинхронно запустить ADOCommand.Execute из основного потока, а из трейда -- рисовать разные ProgressBar до тех пор, пока не упадет флажок ADOCommand.stExecuting, запущенной в основном потоке.
В трейде в строке try OS:=StoredProc.States;exception...end все-таки ловится именно ошибка серверной процедуры, запущенной из основного потока.
В л. случае бол. спасибо.
← →
tyo (2006-03-20 13:59) [12]Смежный вопрос: А если TADOQuery запустить асинхронно -- как из нее потом поймать recordset? Вернее, как отследить что запрос уже отработал?
Вопрос возник из-за того что делаю select из оракловой view, к-рая достаточно долго работает.
Страницы: 1 вся ветка
Текущий архив: 2006.04.02;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.044 c