Асинхронность в управляемом интерфейсе 1С

15.01.17

Разработка - Механизмы платформы 1С

В статье доступно объясняется про новое модное явление асинхронности, добавленное в платформу 1С. Также приложен пример асинхронной обработки по поиску файлов.

Скачать исходный код

Наименование Файл Версия Размер
Обработка, демонстрирующая асинхронный поиск в каталогах файловой системы
.epf 6,58Kb
34
.epf 6,58Kb 34 Скачать

Асинхронность в управляемом интерфейсе 1С

1С на управляемых формах теперь работает на большом количестве платформ – браузеры, мобильные телефоны, Windows, Mac, Linux.

Поэтому некоторые вещи пришлось исключать из 1С, чтобы обеспечить возможность выполнения на разных платформах. Среди этих вещей – синхронность выполнения.

Теперь код 1С должен писаться для асинхронного выполнения. Некоторые ошибочно воспринимают этот факт только в том ключе, что теперь в 1С запрещены модальные окна. Ничего подобного, модальные окна (блокирование всего интерфейса) по-прежнему доступны.

Асинхронность – это совершенно другое, оно затронуло даже то, что не касается интерфейса.

Синхронный и асинхронный код

При выполнении любого кода есть моменты, когда программа занимается ожиданием завершения длительной операции – реакции пользователя, распечатки документа, завершения поиска файлов в каталоге, ответа от интернет-сервера.

В синхронном коде выполняется цикл ожидания завершения длительной операции:

Процедура Работа()
        //Код до длительной операции   
        ВыполнитьДлительнуюОперацию();
                    Пока НЕ ОжиданиеЗавершено() Цикл
                    КонецЦикла
        //Код после длительной операции       
КонецПроцедуры
 

В асинхронном коде выполнение отдается системе при старте длительной операции и возвращается назад программе при завершении этой операции:

Процедура Работа()
        //Код до длительной операции   
        ВыполнитьДлительнуюОперацию(ПродолжениеРаботы);
КонецПроцедуры
Процедура ПродолжениеРаботы ()
        //Код после длительной операции       
КонецПроцедуры
 

В асинхронном коде появляется дробление кода на множество процедур. В-принципе, этого можно было бы избежать неявной генерацией процедур из кода. Т.е. код можно было бы писать как и раньше, система 1С сама бы генерировала процедуры на низком уровне:

Процедура Работа()
        //Код до длительной операции   
                    //На низком уровне завершал бы выполнение процедуры Работа
        ВыполнитьДлительнуюОперацию(ПродолжениеРаботы);  
        //Код после длительной операции, выносился бы в отдельную процедуру на низком уровне  
КонецПроцедуры
 

Процедура Работа может содержать локальные переменные, и вызов длительной процедуры может происходить из середины цикла.

Следовательно, 1С для возрождения контекста процедуры после возвращения выполнения из системы должна восстановить все локальные переменные, переменные цикла и войти так, чтобы оказаться на нужной итерации цикла.

1с не реализовала неявное преобразование обычного кода в асинхронный, переложив тяжесть реализации асинхронности на программиста.

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

Асинхронное выполнение циклов

Асинхронное выполнение снижает читабельность и восприятие программы, провоцирует разбиение дробление кода на мелкие участки.

В синхронном режиме цикл можно было написать так:

Для Инд = 1 По Всего Цикл

        ВыполнитьДлительнуюОперацию();

        ВыполнитьДлительнуюОперацию2();

        //Операторы после длительных операций

КонецЦикла;

 

В асинхронном режиме цикл придется переписать так:

Перем мИнд; //Теперь глобальная переменная
…
мИнд = 0; //Как вариант мИнд = Неопределено;
ИтерацияЦиклаИнд();
…
Процедура ИтерацияЦиклаИнд()
        мИнд = мИнд + 1; //Как вариант мИнд = ? (мИнд = Неопределено, 1, мИнд + 1);
                    Если мИнд >  Всего Тогда
                            Возврат;
        КонецЕсли;
        ВыполнитьДлительнуюОперацию(ВыполнитьДлительнуюОперациюЗавершение);
КонецПроцедуры
 
Процедура ВыполнитьДлительнуюОперациюЗавершение()
        ВыполнитьДлительнуюОперацию2(ВыполнитьДлительнуюОперацию2Завершение);
КонецПроцедуры
 
Процедура ВыполнитьДлительнуюОперацию2Завершение()
                    //Операторы после длительной операций
                    ИтерацияЦиклаИнд (); //Аналог оператора Продолжить
КонецПроцедуры
  

Видно, что нужно явно прописывать вызов следующей итерации. Особенно это важно, если используется цепочка длительных операций, например: сначала получить от пользователя выбор файла, затем получить данные о нем из операционной системы, и т.п.

Переменная Инд для упрощения кода инкрементируется в процедуре итерации до вызова первой длительной операции. Поэтому Инд стартует со значения на единице меньше начального. Как вариант, можно инкрементировать Инд после сравнения с всего, а далее использовать не переменную мИнд, а переменную текущего элемента:

Если мИнд >  Всего Тогда
        Возврат;
        КонецЕсли;
мТекущийЭлемент = мТЗ[Инд];
мИнд = мИнд + 1;

Модальные формы

Что касается модальных форм, то это лишь один из примеров асинхронности. Пожалуй, самый доступный.

Когда вызывается модальная форма, то в асинхронной реализации мы должны прекратить выполнение кода 1с.

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

На самом деле в управляемых формах 1С есть остались модальные окна, это окна которые показываются в режиме «Блокировка всего интерфейса», просто они обрабатываются асинхронным способом.

Плоды асинхронности

Увеличение объема кода

Список процедур, которые требуют асинхронного выполнения, большой.  Это диалоги с пользователем, поиск файлов в каталоге, выполнение команд системы с ожиданием возврата.

Соответственно, код будет часто разбиваться на маленькие кусочки, дробиться на процедуры. Что не будет способствовать прозрачности и удобству восприятия кода.

С другой стороны, программиста все больше и больше приучают к клиент-серверному программированию в парадигме – «послал запрос – жди ответ».

Т.е. классическое программирование последовательного выполнения кода в 1С изживает себя, полностью ломая восприятие программиста для программирования под клиент-серверную архитектуру.

Код в очередной раз усложнился без видимых преимуществ для программиста.

Однако ничего не поделаешь, с этим придется жить и страдать. Интересно, что никакие другие системы кроме 1с не переложили реализацию асинхронности на программиста.

Сохранение и восстановление контекста выполнения

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

Но программисту, так или иначе, придется заботиться о сохранении контекста, что повлечет необходимость написания дополнительного кода. Очередное увеличение трудозатрат.

Независающие формы

Переход на асинхронный код приведет к тому, что даже без фоновых задач можно будет выполнять несколько операций одновременно.

Допустим, была обработка, которая в цикле обрабатывала документы. Управляемая форма передавала управление на сервер и там выполнялась обработка.  В асинхронном варианте придется обработать документ и дождаться возвращения управления от системы. Т.е. после передачи вызова в систему выполнение кода обработки прекратится до получения ответа и пользователь сможет в этом же приложении выполнять другие действия.

Пример асинхронного кода

Я написал обработку, которая выдает список файлов в каталоге. В отличии от типовой, можно обрабатывая отдельно подпапки, чтобы ненужные можно было исключить из результатов. Обработка поиска полностью асинхронная, попробуйте сравнить с обычной.

асинхронность

См. также

Сервисы интеграции без Шины и интеграции

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    2547    dsdred    16    

57

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    5861    dsdred    53    

82

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    5833    YA_418728146    25    

68

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6947    dsdred    36    

113

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    19030    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12741    human_new    27    

76

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    9366    YA_418728146    6    

143

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6518    sebekerga    54    

95
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. FreeArcher 159 16.01.17 05:22 Сейчас в теме
Большое спасибо за статью. Долго думал над этой асинхронностью, зачем да почему... А тут все ответы.
fixin; +1
2. TokAdm 17.01.17 23:51 Сейчас в теме
Статья очень полезная. Автору спасибо, за то , что разложил "по полочкам" вопросы асинхронного кода.
fixin; +1
3. webester 26 18.01.17 17:36 Сейчас в теме
Фиксин наконец то смог понять, что такое запрет модальных окон и решил написать по этому поводу статью?
vano-ekt; starik-2005; pbazeliuk; +3 1
4. Gureev 18.01.17 19:05 Сейчас в теме
На сайте ИТС написано, имхо, намного понятнее.
vano-ekt; davydoff; CyberCerber; fixin; +4
5. fixin 4253 18.01.17 21:46 Сейчас в теме
(4) не скажи, видел я тот ИТС
(3) когда человек говорит мне про "запрет модальных окон", я смеюсь и отвечаю "блокировка всего интерфейса".
+
7. webester 26 19.01.17 04:47 Сейчас в теме
(5)
когда человек говорит мне про "запрет модальных окон", я смеюсь и отвечаю "блокировка всего интерфейса".

Да хоть горшком назови. Суть не меняется. Разработчики это называют именно использованием или не использованием "Режима модальных окон".
не скажи, видел я тот ИТС
И что не устроило? Очень подробное описание, когда использовать, когда не использовать, для чего это нужно, примеры по типовым ситуациям гораздо более информативные, чем здесь, разобраны разные случаи.
+
11. fixin 4253 19.01.17 12:38 Сейчас в теме
(7) важно неиназвание, а суть. Без модальных окон нельзя
.(8) асинхронность можно было сделать прозрачно для программиста 1с на уровне платформы, но платформописатели 1с любят превращать си в ассемблер, излишне напрягая программиста.
+
9. kiv1c 809 19.01.17 10:52 Сейчас в теме
(5) а подскажите ссылку на ИТС пожалуйста
+
10. Bukaska 140 19.01.17 11:01 Сейчас в теме
6. ineshyk 19.01.17 03:39 Сейчас в теме
Это не модное явление, а вынужденные меры для нормальной работы веб клиента.
vano-ekt; +1
12. fixin 4253 19.01.17 21:35 Сейчас в теме
(6) их можно было бы спрятать от программиста в реализации. Незачем программиста нагружать ассемблером
sikuda; +1
25. ineshyk 06.03.17 01:10 Сейчас в теме
(12) ну, смотря какого программиста.
Программиста 1С незачем вообще нагружать разделением директив &НаКлиенте, &НаСервере.
Программист 1С должен знать бух учет, зарплату и макросы писать. Такой себе, "продвинутый бухгалтер".
Так было раньше, по крайней мере, до управляемого интерфейса.
Ignatov_mu; sikuda; +2
29. boln 1040 22.11.17 19:27 Сейчас в теме
(12)
их можно было бы спрятать от программиста в реализации.
Если только в 9.0 :)
Перерабатывать компилятор восьмерки только ради этого уже никто не будет.
+
8. vipetrov2 19.01.17 09:25 Сейчас в теме
Асинхронность нужна не для клиент-серверной архитектуры, а для распаралеливания вычислений. Потому что "ВыполнитьДлительнуюОперацию(ВыполнитьДлительнуюОперациюЗавершение)" и "ВыполнитьДлительнуюОперациюЗавершение()" будут запускаться на стороне сервера, при чем здесь клиент? И вообще 1С это один большой костыль для программиста. Просто разработчики платформы внедряют различные шаблоны проектирования, но при этом получают большие накладные расходы, на свои новшества. И при этом, как кто сгладить негативный эффект они и не собираются. Им вообще ни чего не стоить создать синхронные и асинхронные версии функций. Так нет, например, на стороне клиента с файлами можно работать только асинхронно.
Можно благодаря этой асинхронности сделать индикатор статуса процесса, но опять же за счет слишком трудоемкого процесса обмена между клиент - сервером эта примочка удлинит выполнение на 10-20%.
starik-2005; +1 1
26. ineshyk 06.03.17 01:12 Сейчас в теме
(8)Вы не правы. Асинхронность в 1С нужна чисто для того, чтобы нормально работать в браузере, так как движок JS'а по другому работать не умеет. И открыть просто-так модальное окно, и сказать всей клиентской среде - замри, в веб клиенте не получится.
А работа длительных операций вообще никак не связана с асинхронностью: ни логически, ни физически.
Irwin; boln; +2
27. starik-2005 3036 06.03.17 10:38 Сейчас в теме
(26)
И открыть просто-так модальное окно, и сказать всей клиентской среде - замри, в веб клиенте не получится.
Гыгыгы...
alert('Замрем...');
+
30. sikuda 673 30.10.20 15:46 Сейчас в теме
(26) Точнее работа длительных операций на сервере это и есть асинхронность в 1С. На стороне клиента нет асинхронности, а есть реализация через Оповещения, названная уходим от модальности.
Что такое "асинхронная" реализация функции "ПоказатьВопрос" в 1С - https://www-1c.ru/wp-content/plugins/codemirror1c/run/question/
+
13. starik-2005 3036 19.01.17 23:29 Сейчас в теме
Не хочу придираться к автору, т.к. это, понятное дело, штука бессмысленная. Да и к статье не хочу придираться. Одно понятно - автор вообще не вкурил, что такое асинхронность в контексте "новомодных веяний и в 1С тоже" ))).

Суть термина сама по себе вводит в заблуждение кого угодно, ибо с точки зрения здравого смысла, асинхронность - это возможность выполнять что-то независимо от чего либо другого. Типа нажал кнопку - запустилась какая-то фоновая байда, которая выполнить все, что нам нужно, а мы при этом можем еще какие-то кнопочки нажимать.

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

А вот асинхронность - это когда ты показал диалог пользователю, засунул туда callback-функцию и не ждешь, что ответит тебе пользователь, а занимаешься в это время чем-то другим - просто висишь в ожидании событий. Т.е. при асинхронности ответ пользователя вызовет твою callback-функцию, в которую передаст результат, и который в этой самой отдельной функции и нужно обработать.

А старт длительной операции для получения какого-либо списка (и какой, интересно, идиот сделал получение списка регламентных и фоновых заданий с помощью этого? Стало еще дольше!) - это к асинхронности отношения имеет мало, ибо вместо того, чтобы дернуть calback-функцию формы при получении списка фоновых заданий, приходится висеть в обработке ожидания и мониторить, а не завершилось ли фоновое задание и не нужно ли уже получить список того, что оно нам напилило. Кароче, хрень это, а не асинхронность.

Никаких претензий к автору - как уж понял, так и слава Богу.
Irwin; Ignatov_mu; fixin; lavash67; FilatovRA; vano-ekt; tailer2; +7
14. fixin 4253 20.01.17 07:10 Сейчас в теме
(13) уважаемый, висеть в новомодном 1с у вас не получится. потому что любые циклы ожидания в новомодном 1с запрещены. В этом и есть смысл новомодной асинхронности, которая коснулась не только интерфейсных функций, но и всех функций, где есть ожидание чего-либо - пользователя, принтера, дисковой подсистемы.

Так что это еще вопрос кто читал и не понял и понял не так. ;-)
+
16. starik-2005 3036 20.01.17 11:27 Сейчас в теме
(14)
Так что это еще вопрос кто читал и не понял и понял не так. ;-)
Ну так я и говорю, что асинхронность - это callback'и, а не фоновые задания, которые и раньше были. Тут Вам не надо ничего понимать - достаточно поверить, ибо попытки что-то Вам объяснить сами знаете чем кончатся - потом поймете.
В компьютерном программировании, асинхронные событиями являются те, которые возникают независимо от основного потока выполнения программы. Асинхронные действия — действия, выполненные в неблокирующем режиме, что позволяет основному потоку программы продолжить обработку[6].
Суть тут в том, что есть основной поток, который сгенерировал отображение диалога, при этом основной поток не ждет результата этого диалога, ибо результат обрабатывается в отдельной функции, указанной при открытии этого диалога. То же самое для начала чтения текстового файла, когда он читается независимо от основного потока программы, а после того, как он прочитался, вызывается callback-функция. В итоге нет блокировки ожидания в коде основной программы. Т.е. нет в асинхронном режиме "Результат = Длг.Выбрать()", а есть "Длг.Показать(CallBackFunction);" и продолжение выполнения кода после этого (или выход из процедуры - как будет угодно г-ну программисту). Вот это и есть асинхронность в том понимании, которое связано с "неблокирующим" основной поток выполнением.

В общем не стоит путать фоновые задания, которые и в 8.0 вроде как были, с той "новомодной" асинхронностью, которая методологически убирает модальность. В вебе не так просто организовать ввод данных в диалог, чтобы дождаться результата - там как раз асинхронные механизмы используются. При вводе данных используются calback'и, и даже при рендеринге каждый кадр рассчитывается через вызов callback-функции, которая в конце каждого кадра дергается. Т.е. рендерим объект, отрабатываем логику (меняем состояние объектов на основании событий и поведения), вызываем callback-функцию для отрисовки следующего кадра, пьем чай...

ЗЫ: Как пример предела асинхронности можно привести промисы. Вот это и есть тру-асинхронность, до которой 1С еще пилить и пилить (кстати, тут где-то про промисы в коментах к статье про последовательные асинхронные вызовы было, вот пруф).
Irwin; lavash67; sss_russian; tailer2; +4
15. tailer2 20.01.17 10:32 Сейчас в теме
В отличиЕ от типовой

но это так, придирки

а по существу что-то мне здесь не нравится

вот код из управляемой формы
и что вы думаете?

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ScrptCtrl= Новый COMОбъект("MSScriptControl.ScriptControl");
	ScrptCtrl.Language="vbscript";
// ждет, временный потребитель
ScrptCtrl.AddCode("Dim objService, objEventSource, objEvent, strResult
|Set WinMGMT = GetObject(""winmgmts:\\.\root\cimv2"")
|Set objEventSource = WinMGMT.ExecNotificationQuery (""SEL ECT * FR OM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name ='notepad.exe'"")
|Set objEvent = objEventSource.NextEvent
|");

КонецПроцедуры
Показать


висит, цуко, намертво, пока блокнот не откроешь

**
поясню: если выполнить этот скрипт просто файлом из-под винды, винда продолжает работать, как бы и не ждет наступления события
Прикрепленные файлы:
+
17. spacecraft 20.01.17 12:31 Сейчас в теме
(15)
висит, цуко, намертво, пока блокнот не откроешь

Ну так использован синхронный метод же. Чего ожидали?
Может переписать под асинхронный метод ExecNotificationQueryAsync?
+
18. tailer2 20.01.17 15:22 Сейчас в теме
(17) а ведь я утрудил себя и написал "поясню" :(((

просто запустите этот файлик из-под винды, а потом откройте блокнот
винда не зависнет :)
+
20. spacecraft 20.01.17 16:37 Сейчас в теме
(18) это серьезно сравниваете?
Тогда прямой путь к изучению что такое ОС и чем отличается от программ.
При запуске любого приложения создается отдельный поток. Его еще называют основным потоком приложения.
+
19. tailer2 20.01.17 15:24 Сейчас в теме
(17) на самом деле здесь помогает (ну, может помочь, не всем) понимание, как устроены "аппаратные" прерывания в компутере
+
21. tailer2 20.01.17 16:40 Сейчас в теме
если мне будут нужны советы, я спрошу
+
22. spacecraft 20.01.17 16:44 Сейчас в теме
(21) да я и не давал конкретно вам совет. Просто указал на глупость.
+
23. tailer2 20.01.17 16:46 Сейчас в теме
24. spacecraft 20.01.17 16:52 Сейчас в теме
для чистоты эксперимента:
Запустить этот скрипт в интерпретаторе командной строки без ключевого слова Start.
Потом уже сравнивать с 1С.
+
28. luter-89 22.11.17 17:49 Сейчас в теме
А вопрос перед записью документа? Это ж самый сложный пример, почему не описан? Я изучал по ИТС
Irwin; +1
Оставьте свое сообщение