Вход | Регистрация
 

Вызов для гуру обычных форм - неоправданное обновление всех табличных полей всех форм

Вызов для гуру обычных форм - неоправданное обновление всех табличных полей всех форм
Я
   TormozIT
 
17.10.20 - 07:54
Недавно я победил казалось все проблемы с перенаправлением клавиатурного ввода через внешние события Внешняя компонента для генерации внешнего события при клавиатурном вводе .
Перевел обработку многих глобальных сочетаний клавиш в ИР на этот механизм.
Но пришла теперь другая проблема в обычных формах. И я не вижу способов ее решения. Поэтому обращаюсь к тебе - гуру обычных форм.

Конфигурация ПО

8.1-8.3.18, обычная форма

Проблема

При срабатывании внешнего события или оповещения формам выполняется неоправданное обновление всех табличных полей на активных страницах всех обычных форм, имеющих обработчик соответствующего события

Воспроизведение

Открыть приложенную внешнюю обработку в пустой базе в обычном приложении. Откроется форма с обработчиком оповещения и с двумя страницами, на каждой из которых находится свое табличное поле с обработчиком ПриВыводеСтроки:
Процедура КнопкаВыполнитьНажатие(Кнопка)
ПолучитьФорму("Форма2", ЭтаФорма).Открыть();
КонецПроцедуры
Процедура ТабличноеПоле1ПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Сообщить("ПриВыводеСтроки1 " + ТекущаяДата());
КонецПроцедуры
Процедура ТабличноеПоле2ПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Сообщить("ПриВыводеСтроки2 " + ТекущаяДата());
КонецПроцедуры
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
КонецПроцедуры
Процедура Тест() Экспорт
КонецПроцедуры

В этой форме нажать кнопку "Выполнить". При этом откроется форма "Форма2". В этой форме нажать кнопку "Выполнить". При этом выполнится код
Оповестить();

И в окно сообщений будет выведено

ПриВыводеСтроки1 16.10.2020 18:37:18

А ожидалось отсутствие сообщений.

Если же нажать кнопку "Тест", то выполнится код
ВладелецФормы.Тест();

И сообщений пользователю ожидаемо не выведется. Следовательно просто выполнение кода в форме не приводит к обновлению всех табличных полей ее активных страниц. Почему то именно перед вызовом обработчиков событий ОбработкаОповещения и ОбработкаВнешнегоСобытия платформа делает это. Но зачем?

В документации не нашел объяснения этому поведению. Проблема существует с рождения обычных форм. Впервые столкнулся с ней лет 13 назад.

К чему приводит такое поведение платформы?

Чем больше открыто обычных форм с обработчиками таких событий, тем больше кода выполняется при каждой отправке оповещения формам или внешнего события. Даже если в обработчиках ПриВыводеСтроки и ПриПолученииДанных выполняется только легкий код, то при большом числе форм будет заметна задержка. А уж если есть табличные поля с тяжелыми обработчиками, то тут начинаются много секундные ожидания. Если добавить сюда частую генерацию внешнего события, то получим паралич работы обычного приложения.

Например от этой проблемы страдают механизмы, использующие перехват клавиатурного ввода через внешнее событие, различные рабочие места принимающие события от оборудования.

https://i.imgur.com/22n3GXv.png
https://i.imgur.com/QY4NhDm.png
https://i.imgur.com/lyiVUzM.png
https://i.imgur.com/wwy6ujK.png
Тут можно скачать внешнюю обработку https://www.hostedredmine.com/issues/891484

Посоветуйте, как побороть это всеобщее обновление табличных полей при генерации внешнего события по каждому нажатию клавиши.
   Конструктор1С
 
1 - 17.10.20 - 08:39
Тебе просто нужно научиться делать простой и лаконичный интерфейс, а не изображать "космический корабль в одной форме"
   TormozIT
 
2 - 17.10.20 - 08:47
(1) Спасибо за ответ прямо по теме. Видимо ты очень внимательно прочитал весь текст, глубоко вник в проблему, вспомнил весь свой опыт по описанной проблеме и передал его одной четкой лаконичной фразой. Ты - победитель.
   Конструктор1С
 
3 - 17.10.20 - 08:57
(2) так если так и есть. Большинство проблем интерфейса из-за перегруженности того самого интерфейса. Всего-навсего предлагаю тебе посмотреть на проблему сверху
   Ёпрст
 
4 - 17.10.20 - 09:07
(0) мало где использую ппрривыводестроки ( почтии ниигде) .приаолученииданых ттак же срабаттывает?
   TormozIT
 
5 - 17.10.20 - 09:08
(4) Да
   TormozIT
 
6 - 17.10.20 - 09:09
(3) Если ты так переживаешь за меня и ИР, то почему же тебя нет в чате ИР? Там ты сможешь быстро доставлять мне свое учение и вести меня к свету.
   TormozIT
 
7 - 17.10.20 - 10:02
Ну а про саму проблему кто был в курсе до прочтения этой темы?
   Lexey_
 
8 - 17.10.20 - 10:21
(0) можно в начале обработчика ПриВыводеСтроки добавить
Если Не ВводДоступен() Тогда
Возврат;
КонецЕсли;
   TormozIT
 
9 - 17.10.20 - 10:32
(8) Да. В своих формах такое можно сделать, но при этом у неактивной формы пропадет прикладное оформление. И даже когда она станет активной, оно сразу не появится, т.к. обновление строк не вызовется платформой при активации форомы. А снова оформление выполнится (вызовется обработчик ПриВыводеСтроки), когда юзер что то нужное для обновления строк сделает.
   TormozIT
 
10 - 17.10.20 - 10:33
Но что делать с миллионом чужих форм?
   acht
 
11 - 17.10.20 - 13:10
(0) > Впервые столкнулся с ней лет 13 назад.

Вот это вот хорошо показывает важность и нужность "проблемы". Все остальные на протяжении 13 лет как-то работают без столкновения с ужастиками про "многосекундные ожидания", "паралич работы обычного приложения" и "миллионы чужих форм"

У тебя неестественный сценарий. Никто и пальцем не пошевелит.
   TormozIT
 
12 - 17.10.20 - 13:27
(11) Принимаю твое мнение. Объяснить его могу лишь недостатком опыта. Я все упомянутое видел своими глазами. По поводу ставки на 95% вероятностный вариант исхода - очень мудро. Однако если делать ничего, то там будет 100%.
   acht
 
13 - 17.10.20 - 13:59
Дядь Сереж, а ты и на партнерке так же общаешся?
Или там не так обидно, когда твою безумно важную идею заворачивают?
   mistеr
 
14 - 17.10.20 - 14:01
(0) Платформа 8.2.19.80.
При обработке оповещения вызывается обработчик ПриВыводеСтроки только видимого в данный момент табличного поля.

Цитата из СП для Оповестить(): "Посылает оповещение *всем* созданным формам". Если форма обрабатывает оповещения, то после вызывается ОбновлениеОтображения (можно подключить и проверить). А оно, в свою очередь, приводит к обновлению содержимого табличных полей и вызове соотв. обработчиков. Что в общем-то логично: если форма ловит оповещение, то наверное не просто так, а для того, чтобы что-то поменять у себя и показать это пользователю.

Возможно, в каких-то версиях платформы при обновлении формы дергаются также и не видимые табличные поля. Тут уже ХЗ, возможно сделали какой-то костыль для какого-то сценария в типовых.
   mistеr
 
15 - 17.10.20 - 14:09
(14) Платформа 8.3.10.2505.

При первоначальном вызове Оповестить() (открылась Форма1, нажал Выполнить, открылась Форма2, нажал Выполнить) вызывается только обработчик табличного поля на Страница1.
После активизации Страница2 вызываются обработчики обоих ТП.
Далее при любой активной странице всегда вызываются обработчики обоих ТП.
   TormozIT
 
16 - 17.10.20 - 14:12
(14) Тут нужно уточнить фразу "видимого в данный момент". В объектной модели есть понятия "активная форма", "активная страница", "видимая страница", "видимое табличное поле". Так вот оба табличных поля в примере являются видимыми. Но только первое находится на видимой странице. А сама форма при этом не является активной. При этом эта форма и ее активная страница могут быть невидимы пользователю, т.к. их заслоняет активная форма.
   TormozIT
 
17 - 17.10.20 - 14:13
(15) Т.е. ты воспроизвел проблему. Но непонятно зачем переключал страницы. Я вроде бы не утверждал, что там есть проблемы.
   mistеr
 
18 - 17.10.20 - 14:14
(16) Согласен с поправками. Читать (14) как "на видимой пользователю странице".
   TormozIT
 
19 - 17.10.20 - 14:15
(16) О да я и сам ошибся чуток) -
вместо "только первое находится на видимой странице"
надо "только первое находится на активной странице"
   mistеr
 
20 - 17.10.20 - 14:16
(17) Чтобы понять, есть ли отличия в поведении на разных версиях. Уже вот три разных варианта набралось.
   TormozIT
 
21 - 17.10.20 - 14:17
(20) Ясно. Но главное, что описанное мной в (0) актуально для всех версий 8.* платформы. Даже для 8.0 скорее всего актуально, но у меня ее нет под рукой.
   TormozIT
 
22 - 17.10.20 - 14:18
Различие возможно действительно есть для табличных полей на неактивных страницах.
   mistеr
 
23 - 17.10.20 - 14:19
(21) Ты может не до конца понял. На 8.2.19 проблемы нет. На 8.3.10 есть частично.
   mistеr
 
24 - 17.10.20 - 14:21
Или я не до конца понял проблему. В том, что во всех формах, обрабатывающих оповещения, отрабатывает также обновление отображения, я проблемы не вижу.
   TormozIT
 
25 - 17.10.20 - 14:23
(23) Так я проверял на 8.2 и на 8.1 еще до публикации. Проблема там воспроизводится.
(24) Я же написал что ОЖИДАЛОСЬ - "А ожидалось отсутствие сообщений", т.е. зачем вызывается обновление всех табличных полей? Это неоправданно.
   TormozIT
 
26 - 17.10.20 - 14:26
Если форма выполняет обработчик события ПриЗакрытии - она не обновляет табличные поля. Если выполняет просто какой то свой метод, то тоже не обновляет. При вызове обработки ОбработкаОповещения - она обновляет все (на активных страницах) табличные поля. Ну для активной формы такое еще можно простить, но почему это делается для неактивной формы то?
   mistеr
 
27 - 17.10.20 - 14:31
(26) Логику я попытался объяснить в (14)
   mistеr
 
28 - 17.10.20 - 14:35
При закрытии пользователь ничего не увидит.
После оповещения на форме скорее всего что-то изменилось визуально, поэтому нужно обновить. Например, по-другому раскрасить ячейки в ТП. Метода для ручного обновления формы нет.
Для неактивных просто потому, что оповещения приходят всем.
   TormozIT
 
29 - 17.10.20 - 14:38
(28) Ну а почему при вызове экспортного метода не делается то же самое? Я в (0) это продемонстрировал.
   TormozIT
 
30 - 17.10.20 - 14:39
(28) "Метода для ручного обновления формы нет."
Это некорректное утверждение. У формы есть метод Обновить(). Он вызывает обновление отображения и обновление строк всех табличных полей.
 
 Рекламное место пустует
   TormozIT
 
31 - 17.10.20 - 14:46
(28) По поводу активности формы я согласен, что не стоит делать на этом акцент. Тут важен именно факт вызова обновления отображения при этих событиях и неважно, активна ли форма.
   mistеr
 
32 - 17.10.20 - 14:46
(30) Да, забыл про Обновить()
   mistеr
 
33 - 17.10.20 - 14:54
(29) Потому что просто вызов метода не связан с обновлением визуальной части. А оповещение в большинстве случаев связано. Поэтому платформа делает это сама, чтобы не писать везде Обновить().
   Djelf
 
34 - 17.10.20 - 14:59
(31) Так все верно, это баг. Тут https://its.1c.ru/db/v8std/content/558/hdoc ясно сказано:
> При этом имена событий следует проверять явным образом, чтобы исключить неоправданное обновление списка.
   mistеr
 
35 - 17.10.20 - 15:09
(34) Не вижу связи с нашим случаем. В чем именно баг?

По ссылке разбираются случаи, когда изменились данные в базе, и нужно перечитать динамический список. Это другое.
   RomanYS
 
36 - 17.10.20 - 15:12
(34) Область применения: управляемое приложение
   Djelf
 
37 - 17.10.20 - 15:15
Ну да, недогладел: "Область применения: управляемое приложение, мобильное приложение."
Но имхо, и в обычных формах должно быть так же.
   TormozIT
 
38 - 17.10.20 - 15:18
(33) "Потому что просто вызов метода не связан с обновлением визуальной части"
Очень спорное утверждение. Причем как я уже показал, в объектной модели обычных форм есть все нужное, чтобы точечно обновить всю визуализацию. Зачем же это делать принудительно?
   TormozIT
 
39 - 17.10.20 - 15:18
(38)+ Обновить - и точечно и сразу все.
   RomanYS
 
40 - 17.10.20 - 15:21
(37) Получается в документации об этом не написано, считать багом вроде нельзя. Но по сути готов с формулировкой в (0) согласиться, поведение "неоправданное".
Понятно, что исправлять это никто не планирует. И универсального способа обойти такое поведение для миллионов форм в рамках ветки вероятно не найдётся.
   Djelf
 
41 - 17.10.20 - 15:23
Скорее всего в обычных формах так было изначально сделано, потом для УФ расширили и изменили поведение, а для обычных оставили, чтобы не поломать существующий код.
   Гений 1С
 
42 - 17.10.20 - 15:23
Посылай событие не форме, йопта. Или так нельзя?
т.е. пусть в форме не будет обработка оповещения.
можно ж перебрать все формы
   Гений 1С
 
43 - 17.10.20 - 15:24
т.е. если тебе надо оповестить форму, то вызывай метод, который найдет эту форму и вызовет ее метод ОбработкаОповещения, но не через механизм оповещений. Имхо так, если мне мой Гуру-Тест не изменяет.
   Гений 1С
 
44 - 17.10.20 - 15:25
не помню, в обычных формах можно получить список форм?
   TormozIT
 
45 - 17.10.20 - 15:46
(44) Нет.
   Гений 1С
 
46 - 17.10.20 - 16:13
(45) ну тогда кэшируй оповещения. т.е. вызови один раз, получи ссылку на форму и все. ;-) Хотя не знаю, получится так сделать или нет, ведь при следующем поиске формы придется опять все запрашивать, хз. но попробуй.
   Гений 1С
 
47 - 17.10.20 - 16:21
ну да, можно жы.
т.е. для формы срабатывает обработчик оповещения, он сразу заносит форму в кэш и потом отключает этот обработчик.
при срабатывании оповещения теперь будет вызываться метод формы, а не через оповещение. Норм.
   TormozIT
 
48 - 17.10.20 - 16:37
(47) Да. Для своих форм я уже проработал подобную механику - буферизация обновления отображения неактивных форм, т.е. заносим их в очередь и при добавлении всегда сбрасываем отсчет задержки обработки очереди. Однако с чужими формами проблему похоже без доработки платформы не решить.
   mistеr
 
49 - 17.10.20 - 16:44
Скорее оповещение всех форм — не подходящий механизм для реализации глобальных хоткеев.
   TormozIT
 
50 - 17.10.20 - 16:54
(49) А еще точнее - самый подходящий из доступных.
   mistеr
 
51 - 17.10.20 - 17:20
Надеюсь, будет возможность не использовать эту функцию, завязанную на ВК. Особенно в портативных.
   TormozIT
 
52 - 17.10.20 - 17:49
   Конструктор1С
 
53 - 17.10.20 - 19:03
(0) только почему ты решил, что обновляются именно таблицы? По-моему вызывается обновление всей формы
   TormozIT
 
54 - 17.10.20 - 19:20
(53) Где я утверждал что обновляются только табличные поля? Да, вызывается обновление всей формы, т.е. происходит ровно вызов метода Обновить() формы, т.е. вызывается ОбновлениеОтображения формы и затем обновляются все табличные поля на активных страницах. Однако в обработчике ОбновлениеОтображения в среднем код выполняется на порядке быстрее, чем в обработчиках обновления табличных полей. Поэтому я не стал обозначать эту мелкую деталь.
   Конструктор1С
 
55 - 17.10.20 - 19:31
(54) но ты ведь об этом никак не упомянул. А это ключевое условие, обновление формы влечёт обновление всех элементов. Ну да ладно
   TormozIT
 
56 - 17.10.20 - 19:48
(55) Согласен, что было бы лучше мне сразу об этом упомянуть.
   mistеr
 
57 - 17.10.20 - 21:19
(54) >в обработчике ОбновлениеОтображения в среднем код выполняется на порядке быстрее, чем в обработчиках обновления табличных полей.

Это почему?
   TormozIT
 
58 - 17.10.20 - 21:32
(57) Имеется ввиду не одинаковый код, а среднестатистический (судя по моему опыту) для такого обработчика.
   Сергиус
 
59 - 17.10.20 - 21:50
(0)Ну как бы, 1с уже давно забили на обычные формы, какой смысл с ними возиться?
   TormozIT
 
60 - 17.10.20 - 23:55
 
 Рекламное место пустует
   Сергиус
 
61 - 18.10.20 - 01:38
(60)"И шо?")
   Cyberhawk
 
62 - 18.10.20 - 08:59
(61) Ты за смысл спросил - автор пояснил, ради чего с ними возится
   Гений 1С
 
63 - 18.10.20 - 10:24
(60) Серега, а че, за домен в зоне RU влом башлять 500 в год?
   Гений 1С
 
64 - 18.10.20 - 10:25
(60) И РСЯ там подключить не?
   TormozIT
 
65 - 18.10.20 - 11:33
(64) На этот домен тысячи ссылок. Его любят поисковые системы. Новый домен - большой откат назад по многим позициям.
   Гений 1С
 
66 - 18.10.20 - 11:59
(65) есть такая вэсчь, называется РЕДИРЕКТ.
   Гений 1С
 
67 - 18.10.20 - 12:00
(65) http://devtool1c.ru/ свободен кстати, забронируй покамись за 100 рублей.
   TormozIT
 
68 - 18.10.20 - 12:35
(67) Уже много сообщений не по теме. Лучше обсуждать это в чате ИР или тут в отдельной теме.
   Гений 1С
 
69 - 18.10.20 - 13:43
(68) по теме тупик.
   Гений 1С
 
70 - 18.10.20 - 13:43
а нельзя кстати как-то временно запретить обновление формы в ОФ?
   Гений 1С
 
71 - 18.10.20 - 13:44
(70) попробуй тот же код, но в начале сделай фору невидимой
   TormozIT
 
72 - 18.10.20 - 14:00
(70) Так это и есть краткий вариант вопроса (0)
   Гений 1С
 
73 - 18.10.20 - 15:05
(72) ты попробовал VISIBLE = FALSE, ау? Вызывается обновление?
   Гений 1С
 
74 - 18.10.20 - 15:05
попробуй вставить VISIBLE = FALSE в обработчик оповещения, если что. Потом в теле подключишь обработчик разовый, который делает VISIBLE = TRUE
   Гений 1С
 
75 - 18.10.20 - 15:06
ну можно еще не всю форму невидимой делать пробовать, а только те элементы, которые долго обновляются
   TormozIT
 
76 - 18.10.20 - 15:58
(74) Свойство Visible отсутствует у формы.
   Гений 1С
 
77 - 18.10.20 - 16:43
(76) а у элементов?
   Гений 1С
 
78 - 18.10.20 - 16:43
(76) метод скрыть форму есть, не гони
   Гений 1С
 
79 - 18.10.20 - 17:47
Короче, Серега, что я для тебя протестил.

1. Если в ОбработкаОповещения вызывать исключение, все равно события вызываются.
2. Вызывается также метод ОбновлениеОтображения.
3. Если заткнуть обработчики событий пустыми, то вызываются только пустые, это тебе намек отключать события, чтобы не вызывались:
  Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
      УстановитьДействие("ОбновлениеОтображения", Новый Действие("ОбновлениеОтображения2"));
    ЭлементыФормы.ТабличноеПоле1.УстановитьДействие("ПриВыводеСтроки", Новый Действие("ТабличноеПоле1ПриВыводеСтрокиПустое"));
  КонецПроцедуры
4. Если не щелкать по второй закладке, то не вызывается при выводе строки 2, потому что элемент еще не инициализирован, что ли? Покопай в этом направлении. Может как-то можно сделать элементы не инициализироваными.
5. Попробуй генерить ВнешнееСобытие, оно-то может не вызывает перерисовку формы, хз...
   TormozIT
 
80 - 18.10.20 - 18:34
(79) С внешнего события то все и началось. Если у формы есть его обработчик, то она обновляется сразу после его выполнения.
   Сияющий в темноте
 
81 - 18.10.20 - 18:57
А чем внешнее событие не устроило?
еще можно свой колхоз наколбасить,когда форма регистрируется в списке и у нее вызывается специальный экспортный метод-работает безотказно и на управляемых и на обычных формах.
   TormozIT
 
82 - 18.10.20 - 21:14
(81) Да. Спасибо. В итоге отказался от буферизации обновления форм - очень много визуальных косяков появилось, победил их в большинстве, но все равно прямая отправка победила. Переделал на ведение списка открытых форм и отправку им сообщений через экспортные функции.
   TormozIT
 
83 - 19.10.20 - 07:21
Решил эту проблему для форм ИР https://www.hostedredmine.com/issues/891525
А для остального миллиона обычных форм пришлось отказаться от генерации внешних событий https://www.hostedredmine.com/issues/891475


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.