![]() |
#1 |
Участник
|
![]()
Привет все.
Коллеги, обнаружил интересную особенность использования infolog.yield() Если запустить в аксапте какой то долгий циклический процесс то пока она думает другие открытые окна остаются недоступными. Даже зачастую не перерисовываются нормально. Это ок. Так всегда и было. Пример, джоб ниже. X++: static void TestSysOperationProgress(Args _args) { SysOperationProgress progress; int seconds = 300; int total = seconds * 200; int i; ; info("TestSysOperationProgress"); progress = SysOperationProgress::construct(); progress.setCaption("TestSysOperationProgress"); progress.setTotal(total); for (i = 1; i <= total; i++) { progress.incCount(); progress.setText(strFmt("%1/%2", progress.getCount_RU(), progress.getTotal())); progress.update(true); sleep(5); infolog.yield(); // вглючаем колдунство ! ! ! } info("Конец"); } Что же это получается ? Ядро само открывает новый Thread и разрешает им работать параллельно ? Но ведь они обращаются к разделяемым ресурсам. Например у нас в инфологе написан свой метод заменитель info::messageWinAddLine который пишем инфо в специальную форму написанную на X++ Все запущенные треды джоба обращались при своей работе в этот метод и писали в лог (интересно как ресурсы разделялись, ведь X++ это однопоточный язык ? Что происходило если несколько тредов одновременно дергали метод инфолога ? Или им везло что одновременно не попадали. Или в ядре есть некая блокировка ресурсов так что пока идет вызов от одного треда, остальные ждут в очереди ). Но ошибок не было. Кто-нибудь применял эту особенность ? Какие риски есть ? Это явно что-то недокументированное. Последний раз редактировалось Logger; 16.09.2021 в 13:12. |
|
![]() |
#2 |
Участник
|
Коллеги, еще подсказали что вызов yield позволяет юзеру поменять компанию, так что для параллельно выполняющихся тредов компания неожиданно меняется на другую. Это может быть опасно если используется несколько компаний.
|
|
![]() |
#3 |
Участник
|
В теме (Не)перерисовка окна клиента AX 2009 при длительных операциях - вариант решения немного про infolog.yield().
PS: хм. а там и участник есть Logger |
|
![]() |
#4 |
Участник
|
Спасибо.
Да, я читал эту тему. Но ясности не добавило. Я вообще столкнулся с проблемой, что в цитриксе все периодически подвисает у некоторых юзеров. И изначально решал ее. Грешу на сам цитрикс, но параллельно и саму аксапту проверяю. Думал поставить yield - тогда подвисание одного окошка по идее не должно зафризить весь клиент Аксапты. Но теперь стремно. Еще вроде бы помогает от подвисаний если юзерам включить режим отображения всех окон внутри одной рабочей области. Они это хорошо воспринимают, так как еще недавно работали на 4-ке, а там именно так интерфейс устроен. Такое ощущение что цитрикс / аксапта плохо переваривает ситуацию когда открыто из одной аксапты много (больше 5-7) окошек. Бывают подвисания что не можешь переключиться между окнами. |
|
![]() |
#5 |
Роман Долгополов (RDOL)
|
Да ничего такого потокового магического этот вызов не делает.
Это прям основы винды - кажое окно имеет связанную с ним оконную процедуру Окно это прям не буквально то что юзеры считают окном, а то что имеет HWND - и кнопки и поля ввода и чекбоксы они то же окна Во всяких хитрозагнутых фреймоворках и дотнетах правило что отдельный окошко/контрол - отдельное HWND может уже не соблюдаться, но древнюю по своей сути аксапту до 2012 версии включительно это не касается Общение с окном идет через очередь сообщений - нажатие кнопки клаивиатуры, события мышки, необходимость отрисовки, пользовательсие события - всё это события в очереди сообщений Очередь сообщений разребает оконная процедура - по сути большой SWITCH, который выполняет какие запрограммированные действия в ответ на события в очереди И эта очередь разребается когда поток в котором оконная процедура ничем не занят. Соответственно если занялись чем то безумным надолго, то окно замирает yield всего лишь принудительно вызывает оконные процедуры "вне графика". Отсюда и размораживание интерфейса и иллюзия многопоточности Что там реально случится зависит только от конкретной оконной процедуры. Но абсолютно точно никаких отдельных потоков порождаемых самой системой Блин, каким же древним дедом себя чувствую с этими бесполезными знаниями программиста под винду на голом Си Последний раз редактировалось db; 16.09.2021 в 23:10. |
|
|
За это сообщение автора поблагодарили: mazzy (2), sukhanchik (4). |
![]() |
#6 |
Участник
|
Цитата:
но не до конца. ![]() если бы дело было только в виндах, то метод назывался в духе PeekMessageA и размещался бы где-нибудь в WinAPI, рядышком с методом sendMessage а метод называется yield. и тут стоит вспомнить что X++ - это расширение языка Java, а исполнитель байт-кода (до CIL) - это калька очень древней Java виртуальной машины. а в Java метод с названием yield вполне существует в модуле Thread https://docs.oracle.com/javase/7/doc...ng/Thread.html Цитата:
public static void yield()
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect. It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package. + https://www.baeldung.com/java-thread-yield + https://javarush.ru/quests/lectures/...el07.lecture07 Цитата:
1. другие открытые окна недоступны, поскольку не выполняются служебные потоки в Java, в которых обрабатываются в том числе бизнес-логика аксаптовских контролов и взаимодействие с виндами. так было всегда в аксапте. 2. с некоторой версии windows стала самостоятельно решать, что процесс завис. винда стала по-другому отображать такие окна, ставить специальный статус в таск-менеджере, по-другому выделять память и прочее. а потом в какой-то следующей версии, винда стала по-другому отрисовывать "зависшие" окна. грубо говоря, выполнялся не метод paint, а отрисовка скриншота зависшего окна. а потом в какой-то следующей версии случилось "масштабирование шрифтоф" и... отрисока скриншота сломалась. визуально это выглядит как уменьшенное и размазанное изображение окна. https://superuser.com/questions/9618...not-responding вот это автоопределение зависов и ломает отрисовку окна. а yield даёт подышать джаве, а джава в свою очередь даёт подышать виндам. а подышавшие винды отменяют "kernel panic" и перестает считать клиента аксапты зависшим. Цитата:
https://coub.com/view/2vdi8 Последний раз редактировалось mazzy; 17.09.2021 в 00:31. |
|
|
За это сообщение автора поблагодарили: S.Kuskov (10), SRF (2). |
Теги |
yield |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|