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

15.01.17

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Обработка, демонстрирующая асинхронный поиск в каталогах файловой системы
.epf 6,58Kb
34
34 Скачать (1 SM) Купить за 1 850 руб.

Асинхронность в управляемом интерфейсе 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)

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

23.06.2024    8145    bayselonarrend    20    

156

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

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

13.03.2024    6326    dsdred    18    

80

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

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

24.01.2024    19256    YA_418728146    26    

72

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

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

06.10.2023    24213    SeiOkami    48    

135

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

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

28.08.2023    15249    YA_418728146    7    

169
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. FreeArcher 162 16.01.17 05:22 Сейчас в теме
Большое спасибо за статью. Долго думал над этой асинхронностью, зачем да почему... А тут все ответы.
2. TokAdm 17.01.17 23:51 Сейчас в теме
Статья очень полезная. Автору спасибо, за то , что разложил "по полочкам" вопросы асинхронного кода.
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 4275 18.01.17 21:46 Сейчас в теме
(4) не скажи, видел я тот ИТС
(3) когда человек говорит мне про "запрет модальных окон", я смеюсь и отвечаю "блокировка всего интерфейса".
7. webester 26 19.01.17 04:47 Сейчас в теме
(5)
когда человек говорит мне про "запрет модальных окон", я смеюсь и отвечаю "блокировка всего интерфейса".

Да хоть горшком назови. Суть не меняется. Разработчики это называют именно использованием или не использованием "Режима модальных окон".
не скажи, видел я тот ИТС
И что не устроило? Очень подробное описание, когда использовать, когда не использовать, для чего это нужно, примеры по типовым ситуациям гораздо более информативные, чем здесь, разобраны разные случаи.
11. fixin 4275 19.01.17 12:38 Сейчас в теме
(7) важно неиназвание, а суть. Без модальных окон нельзя
.(8) асинхронность можно было сделать прозрачно для программиста 1с на уровне платформы, но платформописатели 1с любят превращать си в ассемблер, излишне напрягая программиста.
9. kiv1c 818 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 4275 19.01.17 21:35 Сейчас в теме
(6) их можно было бы спрятать от программиста в реализации. Незачем программиста нагружать ассемблером
25. ineshyk 06.03.17 01:10 Сейчас в теме
(12) ну, смотря какого программиста.
Программиста 1С незачем вообще нагружать разделением директив &НаКлиенте, &НаСервере.
Программист 1С должен знать бух учет, зарплату и макросы писать. Такой себе, "продвинутый бухгалтер".
Так было раньше, по крайней мере, до управляемого интерфейса.
Ignatov_mu; sikuda; +2 Ответить
29. boln 1041 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 3091 06.03.17 10:38 Сейчас в теме
(26)
И открыть просто-так модальное окно, и сказать всей клиентской среде - замри, в веб клиенте не получится.
Гыгыгы...
alert('Замрем...');
30. sikuda 677 30.10.20 15:46 Сейчас в теме
(26) Точнее работа длительных операций на сервере это и есть асинхронность в 1С. На стороне клиента нет асинхронности, а есть реализация через Оповещения, названная уходим от модальности.
Что такое "асинхронная" реализация функции "ПоказатьВопрос" в 1С - https://www-1c.ru/wp-content/plugins/codemirror1c/run/question/
13. starik-2005 3091 19.01.17 23:29 Сейчас в теме
Не хочу придираться к автору, т.к. это, понятное дело, штука бессмысленная. Да и к статье не хочу придираться. Одно понятно - автор вообще не вкурил, что такое асинхронность в контексте "новомодных веяний и в 1С тоже" ))).

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

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

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

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

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

Так что это еще вопрос кто читал и не понял и понял не так. ;-)
16. starik-2005 3091 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 Сейчас в теме
А вопрос перед записью документа? Это ж самый сложный пример, почему не описан? Я изучал по ИТС
Оставьте свое сообщение