04.09.2012, 12:58 | #1 |
Участник
|
как выйти из аксапты в строго заданном месте?
Здравствуйте.
Есть задача - при наступлении определенного условия, неважно на каком этапе обработки мы находимся - срочно покинуть аксапту (с обрыванием всех транзакций, с несохранением введенных данных) - просто выйти. Естественно подумал использовать infolog.shutDown(true), не сработало, отсюда 2 вопроса - один на забавный, второй серьезный 1. Сколько раз отработает цикл X++: int i; for (i = 1; i <= 1000; i++) { print i; infolog.shutDown(true); } // WinAPI::exitWindows(#EWX_FORCE) - пробовал - получилось грустно и все равно цикл отработал 1000 раз Спасибо. Ax2009 |
|
04.09.2012, 13:07 | #2 |
Участник
|
Сгенерируйте исключение сразу после вызова infolog.shutDown(true);
|
|
04.09.2012, 13:13 | #3 |
Участник
|
try его ловит дальше по коду
|
|
04.09.2012, 14:20 | #4 |
Участник
|
Я бы смотрел в сторону убийства процесса AX32.exe, например через те же winapi функции
Интересно узнать, зачем вам это понадобилось? |
|
04.09.2012, 14:34 | #5 |
Участник
|
Зачем сразу убийства?.. ExitProcess()
|
|
|
За это сообщение автора поблагодарили: f18 (2). |
04.09.2012, 14:57 | #6 |
Участник
|
lvan
Я бы смотрел в сторону убийства процесса AX32.exe, например через те же winapi функции >> не знал функци, поэтому и спросил :-) Интересно узнать, зачем вам это понадобилось? >> это сложно. Очень грубо говоря багфиксинг. gl00mie Зачем сразу убийства?.. ExitProcess() >> Спасибо - попробую, отпишусь. |
|
04.09.2012, 15:27 | #7 |
Участник
|
Цитата:
Сообщение от gl00mie
Зачем сразу убийства?.. ExitProcess()
Спасибо большое! |
|
04.09.2012, 15:51 | #8 |
Участник
|
определяем ID процесса
X++: static int GetCurrentProcessId() { Dll kernel32 = new Dll(#KERNELDLL); DllFunction processId = new DllFunction(kernel32, "GetCurrentProcessId"); ; processId.returns(ExtTypes:: DWord); return processId.call(); } X++: static void TerminateProcess(int _processId) { Dll kernel32 = new Dll(#KERNELDLL); DllFunction closeHandle = new DllFunction(kernel32, "CloseHandle"); DllFunction terminateProcess = new DllFunction(kernel32, "TerminateProcess"); DllFunction openProcess = new DllFunction(kernel32, "OpenProcess"); int hProcess; closeHandle.returns(ExtTypes:: DWORD); closeHandle.arg(ExtTypes:: DWORD); terminateProcess.returns(ExtTypes:: DWord); terminateProcess.arg(ExtTypes:: DWord, ExtTypes:: DWord); openProcess.returns(ExtTypes:: DWord); openProcess.arg(ExtTypes:: DWord, ExtTypes::DWord, ExtTypes:: DWord); hProcess = openProcess.call(1, false, _processId); terminateProcess.call(hProcess, 1); closeHandle.call(hProcess); } |
|
04.09.2012, 16:11 | #9 |
Участник
|
Если не сложно, для людей не сильно понимающих разницу - в чем принципиальная разница?
|
|
04.09.2012, 16:26 | #10 |
Участник
|
видимо из-за этого: "Функцию TerminateProcess следует использовать только в исключительных случаях, когда исчерпаны все другие способы воздействия на процесс, поскольку она не позволяет потокам процесса выполнить очистку или сохранить данные, а также не оповещает загруженные DLL о завершении процесса."
|
|
|
За это сообщение автора поблагодарили: f18 (1). |
04.09.2012, 16:40 | #11 |
Участник
|
Цитата:
Сообщение от michel1971
видимо из-за этого: "Функцию TerminateProcess следует использовать только в исключительных случаях, когда исчерпаны все другие способы воздействия на процесс, поскольку она не позволяет потокам процесса выполнить очистку или сохранить данные, а также не оповещает загруженные DLL о завершении процесса."
Преднастроенный терминальный клиент с автозапуском аксапты, если аксапта закрывается - закрывается терминальный клиент. Правильно ли я понимаю, что используя TerminateProcess и, как следствие, выход из терминальной сессии, я гарантирую коректность закрытия dll? |
|
04.09.2012, 17:53 | #12 |
Участник
|
Цитата:
мне кажется что у меня написано ровно противоположное |
|
04.09.2012, 18:15 | #13 |
Участник
|
Цитата:
infolog.shutDown(true) всего лишь информирует систему, что Аксапту нужно закрыть когда будет возможность. Аксапта выйдет, когда перейдет в режим ожидания. Пока выполняется код выхода из системы не будет. Не заставляйте выходить из аксапты принудительно. Разбейте задачу на две части: 1. проинфорируйте систему что вы ее хотите закрыть. 2. заставьте ваш код завершить выполнение чтобы заставить ваш код завершить выполнение, не надо ломать dll'ки. достаточно обычных break и return. |
|
04.09.2012, 18:16 | #14 |
Участник
|
Цитата:
Сообщение от f18
Ок, спс! Если у меня аксапта работает след образом
Преднастроенный терминальный клиент с автозапуском аксапты, если аксапта закрывается - закрывается терминальный клиент. Правильно ли я понимаю, что используя TerminateProcess и, как следствие, выход из терминальной сессии, я гарантирую коректность закрытия dll? |
|
04.09.2012, 18:45 | #15 |
Banned
|
А что? Зависание системы в seamless-терминальном окне - это действительно серьезная проблема.
|
|
04.09.2012, 21:57 | #16 |
Участник
|
Цитата:
вызывать sysprogressinfo, вставлять sleep, отдавать управление аксапте через task, обращаться к wait формы... хоть это и неправильно, но лучше чем принудительное убивание dll'ек изнутри самой программы. и еще. стоит четко различать состояния когда: 1. поток кода выполняется в самой аксапте (как в этой теме пример с циклом и тут надо тупо юзать break/return чтобы завершить свой код) и 2. аксапта ждет ответа от SQL-сервера например, массовый апдейт по многоГиговой таблице с огромной вероятностью заблокирует всех на несколько минут. любое прерывание не приведет к немедленному отвисанию и снятию блокировки (даже если аксапту убить), ведь SQL-сервер начнет откатывать транзакцию - еще несколько минут. поэтому задача программиста - корректно завершить выполнение своего кода и уведомить систему, что нужно выйти в винду. |
|
05.09.2012, 01:10 | #17 |
Участник
|
|
|
05.09.2012, 01:25 | #18 |
Участник
|
Цитата:
Сообщение от mazzy
Цикл отработает 1000 раз.
infolog.shutDown(true) всего лишь информирует систему, что Аксапту нужно закрыть когда будет возможность. Аксапта выйдет, когда перейдет в режим ожидания. Пока выполняется код выхода из системы не будет. Не заставляйте выходить из аксапты принудительно. Разбейте задачу на две части: 1. проинфорируйте систему что вы ее хотите закрыть. 2. заставьте ваш код завершить выполнение чтобы заставить ваш код завершить выполнение, не надо ломать dll'ки. достаточно обычных break и return. Стоит делема - остановить пользователей из за иногда возникающей проблемы генерирующей по 4,5 млн записей в лог за 240 минут (а на лог еще и умудрились повесить генератор оповещений, да еще и не один пользователь т.е. 4,5 млн * кол-во пользователей, а потом еще и невозможность открыть аксапту при логине пользователей), или, до выяснения, в своем коде, гарантированно без транзакций при возникновении подозрения на бестактное поведение - просто закрывать аксапту. Да, это не красиво, да может быть прощет в архитектуре и лога и поведении системы, но для того что бы работа не остановилась и было время на корректное исправление и приведения системы с break и return - нужно время и ... вот такая заплатка. |
|
05.09.2012, 01:41 | #19 |
Участник
|
|
|
05.09.2012, 02:10 | #20 |
Участник
|
Цитата:
Цитата:
с другой стороны, сама мысль о том, что TerminateProcess можно использовать в ERP-системе... Причем использовать, чтобы гарантировать корректность... Она отдает такой степенью извращенности, в которую страшно заглянуть. Поэтому и ужас-ужас-ужас |
|