|
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 его ловит дальше по коду
|
|
08.10.2020, 14:41 | #4 |
Участник
|
|
|
04.09.2012, 14:20 | #5 |
Участник
|
Я бы смотрел в сторону убийства процесса AX32.exe, например через те же winapi функции
Интересно узнать, зачем вам это понадобилось? |
|
04.09.2012, 14:34 | #6 |
Участник
|
Зачем сразу убийства?.. ExitProcess()
|
|
|
За это сообщение автора поблагодарили: f18 (2). |
04.09.2012, 14:57 | #7 |
Участник
|
lvan
Я бы смотрел в сторону убийства процесса AX32.exe, например через те же winapi функции >> не знал функци, поэтому и спросил :-) Интересно узнать, зачем вам это понадобилось? >> это сложно. Очень грубо говоря багфиксинг. gl00mie Зачем сразу убийства?.. ExitProcess() >> Спасибо - попробую, отпишусь. |
|
04.09.2012, 15:27 | #8 |
Участник
|
Цитата:
Сообщение от gl00mie
Зачем сразу убийства?.. ExitProcess()
Спасибо большое! |
|
04.09.2012, 15:51 | #9 |
Участник
|
определяем 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 | #10 |
Участник
|
Если не сложно, для людей не сильно понимающих разницу - в чем принципиальная разница?
|
|
04.09.2012, 18:15 | #11 |
Участник
|
Цитата:
infolog.shutDown(true) всего лишь информирует систему, что Аксапту нужно закрыть когда будет возможность. Аксапта выйдет, когда перейдет в режим ожидания. Пока выполняется код выхода из системы не будет. Не заставляйте выходить из аксапты принудительно. Разбейте задачу на две части: 1. проинфорируйте систему что вы ее хотите закрыть. 2. заставьте ваш код завершить выполнение чтобы заставить ваш код завершить выполнение, не надо ломать dll'ки. достаточно обычных break и return. |
|
05.09.2012, 01:25 | #12 |
Участник
|
Цитата:
Сообщение от mazzy
Цикл отработает 1000 раз.
infolog.shutDown(true) всего лишь информирует систему, что Аксапту нужно закрыть когда будет возможность. Аксапта выйдет, когда перейдет в режим ожидания. Пока выполняется код выхода из системы не будет. Не заставляйте выходить из аксапты принудительно. Разбейте задачу на две части: 1. проинфорируйте систему что вы ее хотите закрыть. 2. заставьте ваш код завершить выполнение чтобы заставить ваш код завершить выполнение, не надо ломать dll'ки. достаточно обычных break и return. Стоит делема - остановить пользователей из за иногда возникающей проблемы генерирующей по 4,5 млн записей в лог за 240 минут (а на лог еще и умудрились повесить генератор оповещений, да еще и не один пользователь т.е. 4,5 млн * кол-во пользователей, а потом еще и невозможность открыть аксапту при логине пользователей), или, до выяснения, в своем коде, гарантированно без транзакций при возникновении подозрения на бестактное поведение - просто закрывать аксапту. Да, это не красиво, да может быть прощет в архитектуре и лога и поведении системы, но для того что бы работа не остановилась и было время на корректное исправление и приведения системы с break и return - нужно время и ... вот такая заплатка. |
|
05.09.2012, 09:37 | #13 |
NavAx
|
Цитата:
Сообщение от f18
речь идет о трудно вычислимом баге, и попытке его поймать. То что это концептуально неправильно ясно, но все равно спасибо за дополнительное целенаведение.
Стоит делема - остановить пользователей из за иногда возникающей проблемы генерирующей по 4,5 млн записей в лог за 240 минут (а на лог еще и умудрились повесить генератор оповещений, да еще и не один пользователь т.е. 4,5 млн * кол-во пользователей, а потом еще и невозможность открыть аксапту при логине пользователей), или, до выяснения, в своем коде, гарантированно без транзакций при возникновении подозрения на бестактное поведение - просто закрывать аксапту. Да, это не красиво, да может быть прощет в архитектуре и лога и поведении системы, но для того что бы работа не остановилась и было время на корректное исправление и приведения системы с break и return - нужно время и ... вот такая заплатка. Статус "Отменено" в строках заказа |
|
05.09.2012, 13:37 | #14 |
Участник
|
Цитата:
Сообщение от raz
А если попытаться найти причину?
Статус "Отменено" в строках заказа Итак что есть ... Есть некая логика Класс TSession - хранит в себе информацию о неком пользователе системы, ссылку на TProcess, ссылку на TFormUpdater TProcess - класс выполняющий некую работу в системе, в зависимости от введенной пользователем информации. TFormUpdater обновляется классом TProcess и его заддача хранить текущие переменные для отображения на экране. Логика создавалась не для форм аксапты, но жизнь такова, что есть формы работающие с этими классами и в аксапте - прикреплены примеры форм. На форме только одно окно (СтрингЭдит) для ввода информации. Задачи этого контролла - после нажатия пользователем энтера передать эту информацию в TSession (допустим метод ВВОД) , очистится и перечитать в свои объекты на форме состояние измененного TFormUpdater. TSession вызывает метод ВВОД класса TProcess. В TProcess.ВВОД стоит try catch и если происходит исключительное состояние - запонить инфолог в некий лог, что бы пользователь мог его прочитать. Теперь форма в аксапте. СтрингЭдит - исходя из задач кот перед ним стоят - реализован в виде эдит метода с кодом (набираю руками - могу ошибится) X++: edit str (boolean _set, str _value) { if (set) { TSession.(_value); } return ""; } Как вариант - пользователь ввел какое-то значение в СтрингЭдит, нажал на форме эскейп, форма спросила - Я Изменилась, сохранить незаписаннные данные - а пользователь нажал - сохранить ... Возможные направления исправления ошибки - отказаться от эдит метода и отрабатывать просто модифай + попросить форму не заадавать вопроса, но здесь сложнее, обработка многошаговая, есть шаги когда вопрос просто необходимо задавать. Трай в эдит методе не могу делать - большая обработка инфолога + не факт что такое же можно будет сделать в форме не аксапты. Пока до форм не аксапты не добрались - и ошибку не пофиксили было принято решение пользователям продолжать работать в системе, уведомить что бы все отказывались от всего предлагаемого + жуть-жуть-жжжжжуть. |
|
05.09.2012, 14:29 | #15 |
NavAx
|
Если я правильно понимаю, то лог - это некий доработанный лог, не SysDataBaseLog аксапты, причем это таблица.
Если я прав, то можно настоить журнал базы данных на эту таблицу, и, после повторения проблемы, проанализировать стек вызовов. |
|
04.09.2012, 18:45 | #16 |
Banned
|
А что? Зависание системы в seamless-терминальном окне - это действительно серьезная проблема.
|
|
04.09.2012, 21:57 | #17 |
Участник
|
Цитата:
вызывать sysprogressinfo, вставлять sleep, отдавать управление аксапте через task, обращаться к wait формы... хоть это и неправильно, но лучше чем принудительное убивание dll'ек изнутри самой программы. и еще. стоит четко различать состояния когда: 1. поток кода выполняется в самой аксапте (как в этой теме пример с циклом и тут надо тупо юзать break/return чтобы завершить свой код) и 2. аксапта ждет ответа от SQL-сервера например, массовый апдейт по многоГиговой таблице с огромной вероятностью заблокирует всех на несколько минут. любое прерывание не приведет к немедленному отвисанию и снятию блокировки (даже если аксапту убить), ведь SQL-сервер начнет откатывать транзакцию - еще несколько минут. поэтому задача программиста - корректно завершить выполнение своего кода и уведомить систему, что нужно выйти в винду. |
|
05.09.2012, 14:47 | #18 |
NavAx
|
Ну жжжуткий фикс наверно стоит оставить, до нахождения причин. Ну и не факт, что стек поможет. Кстати, стек можно и добавить в TLog (если что), а может и еще чего туда писать (значения переменных...) для последующего анализа.
|
|
05.09.2012, 14:51 | #19 |
Участник
|
|
|
08.10.2020, 15:51 | #20 |
Участник
|
лови некроманта!
|
|