|
18.11.2011, 19:26 | #1 |
Участник
|
Классы от RunBaseReport и класс Thread
Добрый вечер, Уважаемые коллеги.
У меня возникает интерес, узнать Ваше мнение в связи с тем, чем мне пришлось в последнее время заниматься. У нас много отчетов, которые используют стандартный базовый класс RunBaseReport. Многие бухгалтера, экономисты и т.д. недовольны тем, что после запуска отчета Система зависает.Я, понимаю, есть архив печати, запуск в пакете и т.д.Но им хочется простоты. Для этого можно использовать класс Thread. Если весь алгоритм выполнения запустить в его(Thread) Run, то Axapta становится доступна, т.е. проще говоря, диалоговое окно исчезает, и делай что хочешь.Бегай по справочникам, запускай другие отчеты.Отчет сам выйдет на экран, когда отработает. А все дело в том, что открывается новая сессия с типом - Рабочая. Это очень удобно пользователям.Плюс экономит время.Если в отчете есть независимые от себя блоки получения информации, то вместо последовательного режима выполнения, они будут выполняться в параллельном. Правда есть нюанс : после каждого Thread создается новая сессия с типом Рабочая. (я надеюсь она не влияет на лицензии?). И только тогда, когда Thread завершится, сессия закроется. Интересно узнать Ваше мнение, рационально ли использовать такой подход для большинства отчетов, ради удобства работы пользователей?
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. |
|
18.11.2011, 20:11 | #2 |
Участник
|
Было несколько тем на форуме по thread
Описание функций класса Thread Визульное сравнение различных алгоритмов сортировки Threads Из них для себя вынес, понимание того что в 3-ке этот класс был достаточно глючным и пользоваться им на клиенте не рекомендовалось самими разработчиками MS. Только на сервере. Плюс глючило в двухзвенке. Как обстоит дело в 2009-й не знаю. Как-то мне этот класс не нравится. Не принято им пользоваться, поэтому зачем изобретать велосипед ? Я бы предложил вам лучше ставить построение отчетов в пакет, с уведомлением которое покажет пользователю всплывающее окно. Можно это дело навернуть как нить, например сделать формочку, которая по таймеру аналогично sidax будет показывать прогресс выполнения отчета в фоне, пока пользователь делает остальные дела. |
|
|
За это сообщение автора поблагодарили: Pustik (1). |
18.11.2011, 20:22 | #3 |
Участник
|
Почему ?
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. |
|
18.11.2011, 21:39 | #4 |
Участник
|
|
|
18.11.2011, 22:20 | #5 |
Участник
|
Как мне кажется, из-за потенциальных багов в реализации, увеличение стоимости разработки и тестирования и увеличение сроков выпусков.
-потому что надо редизайнить реализацию алгоритмов (при том что не все хорошо поддаются распраллеливанию) -необходимо иметь обертки над примитивами синхронизации, представлять работу процессора, памяти, ОС, взаимодействие с GUI, COM и т.п. Т.е. заниматься низкоуровневой разработкой, для чего Аксапта совсем не предназначена. Но правильное использование класса Thread позволяет довольно эффективно решать проблему производительности на конкретной инсталляции.
__________________
Sapere aude Последний раз редактировалось Diman; 18.11.2011 в 22:29. |
|
19.11.2011, 00:37 | #6 |
Участник
|
Цитата:
Сообщение от Pustik
RunBaseReport. Многие бухгалтера, экономисты и т.д. недовольны тем, что после запуска отчета Система зависает.Я, понимаю, есть архив печати, запуск в пакете и т.д.Но им хочется простоты. Для этого можно использовать класс Thread. Если весь алгоритм выполнения запустить в его(Thread) Run, то Axapta становится доступна, т.е. проще говоря, диалоговое окно исчезает, и делай что хочешь.
Цитата:
Сообщение от Blog bot
A customer runs into a situation where the functionality that they receive through AX is not what they expected. This piece of functionality is key for the customer and they aren't happy that the product was designed in this manner. You realize that this is important to the customer, but the chances of the product being changed to accommodate this request are extremely small. In your opinion, what's the best way to handle this?
Here I'm trying to see how quickly they go to "make customizations". I want them to communicate the truth to the customer and exhaust other options before moving to creating the customization |
|
19.11.2011, 01:30 | #7 |
Участник
|
Еще, пакетными обработчиками удобно управлять и перезапускать при какой либо ошибке. Для потоков ничего этого нет и придется самим все это написать.
|
|
19.11.2011, 04:17 | #8 |
Участник
|
Поделюсь одним изысканием по поводу Thread
Недавно обнаружил, что при изменении данных сторонними средствами в EntireTable кешируемых табличках или при выполнении к таким табличкам прямых запросов SQL на обновление - кеш не только видит этих изменений, но и не хочет сбрасываться обычными способами. (Подчеркну - речь идет именно о прямых запросах SQL к базе, формируемых например при дублировании компаний класом SysSqlCopyCompany) Эта особенность в 2009-й Аксапте особено опасна тем что аосы можно долго не перестартовывать (в отличие от трешки). У нас, например, пакетный сервер неделями может без перестарта жить. Попробовал сбрасывать кеш вызовом Меню-Сервис-Средства разработки-Объекты приложения-Обновить данные Не работает. После некоторых разбирательств выяснилось, что необходимо сбрасывать именно серверный кеш. Поправили менюитем SysFlushData -на одном аосе все ок. А в кластере аосов все равно кеш не сбрасывается. Вместе с тем при вызове класса по менюитему SysFlushData - пишется информация в лог SysEvent, который должны читать служебные сессии на других аосах и обрабатывать сброс кеша. (Класс SysEventHandler ) Но как видно из этого примера, ожидаемой обработки лога SysEvent не происходит. После некоторых разбирательств удалось понять, что при старте АОСа он создает 2 системные сессии с SessionID равным 1 и 2. В каждой из этих сессий при вызове Application.new() происходит вызов SysEventHandler::initialize(); Далее идет попытка создать отдельный поток при помощи класса Thread и в нем запустить на выполнение статический метод SysEventHandler::runHandler таким вызовом X++: thread.run(classnum(SysEventHandler),staticmethodstr(SysEventHandler,runHandler)); Т.е. обработчик событий не работает и кеши на аосах в кластере не сбрасываются. (Также возможно не сбрасывается кеш AOT и словаря и настройки логирования sysDatabaseLog - детально проверить руки не дошли.) Если же извратиться и из джоба запустить таки описанный обработчик, например так SysEventHandler::initialize(true); то все же можно заставить работать данный обработчик. В этом случае при вызове X++: thread.run(classnum(SysEventHandler),staticmethodstr(SysEventHandler,runHandler)); Но! Работает он все равно как-то глючно. Например если в SysEvent послать событие SysEventType::EventHandlerPing то оно успешно обработается и в ответ отправится событие SysEventType::EventHandlerAlive Так что если из 3-ки в 2009-й поднять форму SysEventManagement, то в ней как раз можно увидеть результаты использования этих событий - она успешно опрашивает все работающие аосы в кластере и выводит их перечень. Но если послать событие SysEventType::FlushData - а именно оно и отправляется при сбросе кеша, то почему-то в силу невыясненных причин кеш не сбрасывается. Т.е. код работает но как то "не до конца" Т.е. если на сервере запускается код X++: Dictionary::dataFlush(); P.S. Ax2009 build 4570 (RU7) Приложение RU5 Кстати, кто-нибудь умеет гарантированно сбрасывать кеш табличек в кластере аосов ? Поделитесь. Последний раз редактировалось Logger; 19.11.2011 в 04:42. |
|
|
За это сообщение автора поблагодарили: Wamr (10), fed (15), sukhanchik (8), lev (10), gl00mie (9). |
19.11.2011, 21:56 | #9 |
Участник
|
Спасибо всем, я понимаю так, что это не лучшее решение.
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. |
|
09.11.2015, 15:07 | #10 |
Участник
|
Цитата:
Оказывается они еще и ведут себя по разному. Сессия 1 считает что curExt() = "" ! Как следствие, если захочется что-то по логировать то для нее не получится это сделать (поймать момент старта аоса и записать в табличный лог). Тупо выдает ошибку Цитата:
Object Server XX: Dialog issued for client-less session 1: Cannot create a record in YYYYYYY (ZZZZZ).
Insert operations are not allowed across companies. Please use changecompany keyword to change the current company before inserting the record. |
|
20.11.2011, 16:49 | #11 |
Участник
|
Цитата:
Если бокс установлен - отправлять отчет на выполнение в пактный режим на определенную группу пакетов. Канал вывода при этом установить в "файл" или "архив печати". (в зависимости от предпочтительного способа визуализации). На клиенте в этот момент стартует таймер, который опрашивает, например, раз в 10 секунд архив печати или некую промежуточную таблицу в которую пишется имя созданного файла отчета для данного пользователя. При появлении в архиве печати новой записи для данного пользователя - вывести этот отчет пользователю на экран. (Если вывод в файл - скопировать его с сервера во временную папку клиента пользователя и открыть Word-ом или PDF - viewer - ом в зависимости от предпочтительного формата). А еще можно отправлять готовые отчеты, по завершению пакетной обработки, пользователю на почту в виде файла. (Делаю так с отчетами excel) Вообще, думаю тема построения отчетов в отдельном потоке актуальна. Встречал некоторые системы автоматизации, где так и сделано. Можно было бы встроить поддержку этого и в стандартный функционал Аксапта... Последний раз редактировалось someOne; 20.11.2011 в 16:51. |
|
|
За это сообщение автора поблагодарили: Pustik (3). |
21.11.2011, 08:53 | #12 |
Участник
|
Цитата:
Сообщение от someOne
А еще можно отправлять готовые отчеты, по завершению пакетной обработки, пользователю на почту в виде файла.
(Делаю так с отчетами excel) Вообще, думаю тема построения отчетов в отдельном потоке актуальна. Встречал некоторые системы автоматизации, где так и сделано. Можно было бы встроить поддержку этого и в стандартный функционал Аксапта... |
|
|
За это сообщение автора поблагодарили: Maxim Gorbunov (1). |
21.11.2011, 10:15 | #13 |
Возьми свет!!!
|
А вообще может ли серверный thread(я не говорю про клиентский из за которого приложение довольно часто виснет) вообще использовать что то связанное с вводом выводом на экран?
( я иногда в threade убирал не то что info("") я выброс ошибки убирал и все работало) у меня не получалось ни разу, недавно серверный thread не выполнялся только из-за того что у меня в коде было написано appl.curTransactionId(). А так ф принципе каких-то проблем с серверным thread вообще не замечал, работает нормально.
__________________
Axapta 3.0 sp 5 Oracle Я могу взорвать вам мозг!!! |
|
21.11.2011, 11:39 | #14 |
Участник
|
|
|
21.11.2011, 13:22 | #15 |
Возьми свет!!!
|
Я же говорю, там очень много заморочек. Во первых у нити которую вы запускаете не должно вообще ничего быть такого связанного с вводом-выводом иначе она работает только до определенного шага, лучше написать сейчас попроще потом дописывать туда уже что-то, я именно так и делал, каждый раз запуская и проверяя отработает или нет.
Можно класс например проверить который у вас этот поток запускает, выполняется ли он точно на сервере, было у меня такое как-то. Можно даже попробовать что-то вставлять в таблицу и выяснить на каком шаге у вас прерывается работа серверной нити, я так делал. А вот клиентская нить, это вообще отдельная тема. Клиентское приложение если переключится с него, а потом снова попытаться включится - виснет.
__________________
Axapta 3.0 sp 5 Oracle Я могу взорвать вам мозг!!! |
|
|
За это сообщение автора поблагодарили: Logger (5). |
21.11.2011, 13:37 | #16 |
Участник
|
Цитата:
Сообщение от Murlin
Я же говорю, там очень много заморочек. Во первых у нити которую вы запускаете не должно вообще ничего быть такого связанного с вводом-выводом иначе она работает только до определенного шага, лучше написать сейчас попроще потом дописывать туда уже что-то, я именно так и делал, каждый раз запуская и проверяя отработает или нет.
Можно класс например проверить который у вас этот поток запускает, выполняется ли он точно на сервере, было у меня такое как-то. Можно даже попробовать что-то вставлять в таблицу и выяснить на каком шаге у вас прерывается работа серверной нити, я так делал. А вот клиентская нить, это вообще отдельная тема. Клиентское приложение если переключится с него, а потом снова попытаться включится - виснет. Я там все перепроверил. Выше описано. Причина "нерабочести" потока не в том что я заставляю его писать в файл на диск. Он и без моих кастомизаций не работает. Не откликается на сообщения в EventLog. А если вручную на клиенте запустить, то откликается, то есть работает. И даже в файл на диск пишет. |
|
08.08.2013, 19:42 | #17 |
Участник
|
Всем добрый вечер
есть следующая проблема : есть пакетник который в порядке очереди обрабатывает некие запросы, хотелось бы эту последовательную очередь распараллелить но при работе пакетника ничего не происходит при запуске X++: t.run(classnum(MyClass), staticmethodstr(MyClass, MyMethod)); точно проверено : пакетник работает (обрамлял t.run логированием) делал логирование в самом методе MyMethod (тут люди писали что, возможно, валится где то на IO или еще на чем то) - метод вообще не вызывается подскажите куда рыть ? Последний раз редактировалось Omeo; 08.08.2013 в 19:45. |
|
21.11.2011, 10:55 | #18 |
Участник
|
а зачем тогда вообще нужен этот thread??? распараллеливать вычисления типа всяких "ну очень крутых" алгоритмов? если зависать он зависает, работать с ним толком невозможно, для отчётов всё равно его приспособить нельзя. Смысл тогда его?
|
|
21.11.2011, 11:49 | #19 |
Участник
|
Я тоже занимался разработкой мега-отчета, в котором я получаю информацию с разных уголков Аксапты. Приспособил класс thread распараллелил алгоритм и пока проблем никаких нет. Все просто летает. Увеличение производительности в n-крат раз.
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. |
|
21.11.2011, 12:03 | #20 |
Участник
|
Цитата:
значит он не просто неправильно работает, а его лишь неправильно применяют |
|
Теги |
sysevent, thread |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|