Как процедуру запустить асинхронно 1с
1С на управляемых формах теперь работает на большом количестве платформ – браузеры, мобильные телефоны, Windows , Mac , Linux .
Поэтому некоторые вещи пришлось исключать из 1С, чтобы обеспечить возможность выполнения на разных платформах. Среди этих вещей – синхронность выполнения.
Теперь код 1С должен писаться для асинхронного выполнения. Некоторые ошибочно воспринимают этот факт только в том ключе, что теперь в 1С запрещены модальные окна. Ничего подобного, модальные окна (блокирование всего интерфейса) по-прежнему доступны.
Асинхронность – это совершенно другое, оно затронуло даже то, что не касается интерфейса.
Синхронный и асинхронный код
При выполнении любого кода есть моменты, когда программа занимается ожиданием завершения длительной операции – реакции пользователя, распечатки документа, завершения поиска файлов в каталоге, ответа от интернет-сервера.
В синхронном коде выполняется цикл ожидания завершения длительной операции:
В асинхронном коде выполнение отдается системе при старте длительной операции и возвращается назад программе при завершении этой операции:
В асинхронном коде появляется дробление кода на множество процедур. В-принципе, этого можно было бы избежать неявной генерацией процедур из кода. Т.е. код можно было бы писать как и раньше, система 1С сама бы генерировала процедуры на низком уровне:
Процедура Работа может содержать локальные переменные, и вызов длительной процедуры может происходить из середины цикла.
Следовательно, 1С для возрождения контекста процедуры после возвращения выполнения из системы должна восстановить все локальные переменные, переменные цикла и войти так, чтобы оказаться на нужной итерации цикла.
1с не реализовала неявное преобразование обычного кода в асинхронный, переложив тяжесть реализации асинхронности на программиста.
Необходимость преобразования кода из синхронного в асинхронный связана с тем, что в некоторых платформах и системах нельзя крутить бесконечный цикл с вызовом DoEvents . Например, в браузерах выполнение кода должно завершаться в ограниченные сроки.
Асинхронное выполнение циклов
Асинхронное выполнение снижает читабельность и восприятие программы, провоцирует разбиение дробление кода на мелкие участки.
В синхронном режиме цикл можно было написать так:
В асинхронном режиме цикл придется переписать так:
Видно, что нужно явно прописывать вызов следующей итерации. Особенно это важно, если используется цепочка длительных операций, например: сначала получить от пользователя выбор файла, затем получить данные о нем из операционной системы, и т.п.
Переменная Инд для упрощения кода инкрементируется в процедуре итерации до вызова первой длительной операции. Поэтому Инд стартует со значения на единице меньше начального. Как вариант, можно инкрементировать Инд после сравнения с всего, а далее использовать не переменную мИнд, а переменную текущего элемента:
Модальные формы
Что касается модальных форм, то это лишь один из примеров асинхронности. Пожалуй, самый доступный.
Когда вызывается модальная форма, то в асинхронной реализации мы должны прекратить выполнение кода 1с.
Выполнение кода возобновляется, когда пользователь закрыл модальное окно и передается в процедуру, назначенную как обработчик оповещения этого события.
На самом деле в управляемых формах 1С есть остались модальные окна, это окна которые показываются в режиме «Блокировка всего интерфейса», просто они обрабатываются асинхронным способом.
Плоды асинхронности
Увеличение объема кода
Список процедур, которые требуют асинхронного выполнения, большой. Это диалоги с пользователем, поиск файлов в каталоге, выполнение команд системы с ожиданием возврата.
Соответственно, код будет часто разбиваться на маленькие кусочки, дробиться на процедуры. Что не будет способствовать прозрачности и удобству восприятия кода.
С другой стороны, программиста все больше и больше приучают к клиент-серверному программированию в парадигме – «послал запрос – жди ответ».
Т.е. классическое программирование последовательного выполнения кода в 1С изживает себя, полностью ломая восприятие программиста для программирования под клиент-серверную архитектуру.
Код в очередной раз усложнился без видимых преимуществ для программиста.
Однако ничего не поделаешь, с этим придется жить и страдать. Интересно, что никакие другие системы кроме 1с не переложили реализацию асинхронности на программиста.
Сохранение и восстановление контекста выполнения
Если раньше код мог целиком выполняться на сервере, то теперь, при необходимости получить атрибуты файла или другой длительной операции, придется сохранять текущие рассчитанные на сервере данные в хранилище. Причем сохранять не до следующего вызова сервера, а до востребования, потому что до момента, когда они понадобятся, сервер может быть вызван для других операций. Затем их восстанавливать и продолжать на очередной итерации. Т.е. накладные расходы увеличиваются. С другой стороны, по сравнению с длительным ожиданием результата операции накладные расходы по восстановлению контекста составляют крайне небольшой процент.
Но программисту, так или иначе, придется заботиться о сохранении контекста, что повлечет необходимость написания дополнительного кода. Очередное увеличение трудозатрат.
Независающие формы
Переход на асинхронный код приведет к тому, что даже без фоновых задач можно будет выполнять несколько операций одновременно.
Допустим, была обработка, которая в цикле обрабатывала документы. Управляемая форма передавала управление на сервер и там выполнялась обработка. В асинхронном варианте придется обработать документ и дождаться возвращения управления от системы. Т.е. после передачи вызова в систему выполнение кода обработки прекратится до получения ответа и пользователь сможет в этом же приложении выполнять другие действия.
Пример асинхронного кода
Я написал обработку, которая выдает список файлов в каталоге. В отличии от типовой, можно обрабатывая отдельно подпапки, чтобы ненужные можно было исключить из результатов. Обработка поиска полностью асинхронная, попробуйте сравнить с обычной.
Обработка, демонстрирующая асинхронный поиск в каталогах файловой системыСпециальные предложения
(3) когда человек говорит мне про "запрет модальных окон", я смеюсь и отвечаю "блокировка всего интерфейса". когда человек говорит мне про "запрет модальных окон", я смеюсь и отвечаю "блокировка всего интерфейса".
Да хоть горшком назови. Суть не меняется. Разработчики это называют именно использованием или не использованием "Режима модальных окон".
И что не устроило? Очень подробное описание, когда использовать, когда не использовать, для чего это нужно, примеры по типовым ситуациям гораздо более информативные, чем здесь, разобраны разные случаи. (7) важно неиназвание, а суть. Без модальных окон нельзя
.(8) асинхронность можно было сделать прозрачно для программиста 1с на уровне платформы, но платформописатели 1с любят превращать си в ассемблер, излишне напрягая программиста. Это не модное явление, а вынужденные меры для нормальной работы веб клиента. (6) их можно было бы спрятать от программиста в реализации. Незачем программиста нагружать ассемблером
(12) ну, смотря какого программиста.
Программиста 1С незачем вообще нагружать разделением директив &НаКлиенте, &НаСервере.
Программист 1С должен знать бух учет, зарплату и макросы писать. Такой себе, "продвинутый бухгалтер".
Так было раньше, по крайней мере, до управляемого интерфейса.
их можно было бы спрятать от программиста в реализации. Если только в 9.0 :)
Перерабатывать компилятор восьмерки только ради этого уже никто не будет. Асинхронность нужна не для клиент-серверной архитектуры, а для распаралеливания вычислений. Потому что "ВыполнитьДлительнуюОперацию(ВыполнитьДлительнуюОперациюЗавершение)" и "ВыполнитьДлительнуюОперациюЗавершение()" будут запускаться на стороне сервера, при чем здесь клиент? И вообще 1С это один большой костыль для программиста. Просто разработчики платформы внедряют различные шаблоны проектирования, но при этом получают большие накладные расходы, на свои новшества. И при этом, как кто сгладить негативный эффект они и не собираются. Им вообще ни чего не стоить создать синхронные и асинхронные версии функций. Так нет, например, на стороне клиента с файлами можно работать только асинхронно.
Можно благодаря этой асинхронности сделать индикатор статуса процесса, но опять же за счет слишком трудоемкого процесса обмена между клиент - сервером эта примочка удлинит выполнение на 10-20%. (8)Вы не правы. Асинхронность в 1С нужна чисто для того, чтобы нормально работать в браузере, так как движок JS'а по другому работать не умеет. И открыть просто-так модальное окно, и сказать всей клиентской среде - замри, в веб клиенте не получится.
А работа длительных операций вообще никак не связана с асинхронностью: ни логически, ни физически.
И открыть просто-так модальное окно, и сказать всей клиентской среде - замри, в веб клиенте не получится.
Не хочу придираться к автору, т.к. это, понятное дело, штука бессмысленная. Да и к статье не хочу придираться. Одно понятно - автор вообще не вкурил, что такое асинхронность в контексте "новомодных веяний и в 1С тоже" ))).
Суть термина сама по себе вводит в заблуждение кого угодно, ибо с точки зрения здравого смысла, асинхронность - это возможность выполнять что-то независимо от чего либо другого. Типа нажал кнопку - запустилась какая-то фоновая байда, которая выполнить все, что нам нужно, а мы при этом можем еще какие-то кнопочки нажимать.
Но с точки зрения это самой "новомодности", асинхронность - это отсутствие прямой последовательности между командами. Т.е. есть у тебя вопрос пользователю. Синхронность - это когда ты открываешь пользователю диалог с вопросом и ждешь ответа, как соловей лета. Т.е. команды дальше не выполняются, ждется ответ, после которого уже можно посмотреть, что же это самое модальное окно нам вернуло и, соответственно, обработать результат.
А вот асинхронность - это когда ты показал диалог пользователю, засунул туда callback-функцию и не ждешь, что ответит тебе пользователь, а занимаешься в это время чем-то другим - просто висишь в ожидании событий. Т.е. при асинхронности ответ пользователя вызовет твою callback-функцию, в которую передаст результат, и который в этой самой отдельной функции и нужно обработать.
А старт длительной операции для получения какого-либо списка (и какой, интересно, идиот сделал получение списка регламентных и фоновых заданий с помощью этого? Стало еще дольше!) - это к асинхронности отношения имеет мало, ибо вместо того, чтобы дернуть calback-функцию формы при получении списка фоновых заданий, приходится висеть в обработке ожидания и мониторить, а не завершилось ли фоновое задание и не нужно ли уже получить список того, что оно нам напилило. Кароче, хрень это, а не асинхронность.
Асинхронная концепция программирования заключается в том, что результат выполнения функции доступен не сразу же, а через некоторое время в виде некоторого асинхронного (нарушающего обычный порядок выполнения) вызова.
Т.е. главная идея асинхронного программирования заключается в том, чтобы запускать отдельные вызовы методов и параллельно продолжать выполнять другую работу без ожидания окончания вызовов.
Некоторые методы, вероятность исключений которых сведена к минимуму, не нуждаются в асинхронном подходе, но другие - требуют его в самом начале разработки.
Как видно из графиков, коэффициент полезных интерактивных действий пользователя при синхронной модели программирования отсутствует, так как система блокирует пользовательский интерфейс, в то время как при асинхронной модели, пользователь продолжает активную работу в системе.
При синхронном выполнении у приложения есть только один поток. С помощью асинхронной модели программирования вы можете запускать множество параллельных потоков и во время их выполнения реагировать на новые действия пользователя. После того как n-поток выполнен, вы отображаете результат на экран.
Фоновые задания в «1С:Предприятие 8»
В «1С:Предприятие 8» фоновые задания предназначены для выполнения прикладных задач асинхронно. Они могут порождать дочерние фоновые задания, например, для распараллеливания сложных вычислений по различным рабочим серверам кластера в клиент-серверном варианте работы.
Существует возможность ограничить выполнение фоновых заданий, имеющих одинаковые методы, по определенному прикладному признаку. Программное создание и управление фоновыми заданиями возможно из любого соединения пользователя с информационной базой системы. Фоновое задание выполняется от имени пользователя, который его создал.
Механизм заданий функционирует как в клиент-серверном, так и в файловом варианте работы, но возможности по администрированию и выполнению заданий в обоих вариантах несколько различаются.
В клиент-серверном варианте планированием выполнения заданий занимается планировщик заданий, который физически располагается в менеджере кластера.
Планировщик периодически проверяет, не поступили ли запросы на выполнение фоновых заданий. Если есть задания, которые нужно выполнить, планировщик определяет наименее загруженные рабочие процессы кластера и последовательно назначает каждому из них свое задание на выполнение. Таким образом, один и тот же рабочий процесс потенциально может выполнять несколько заданий параллельно. После того как задание получено рабочим процессом, рабочий процесс устанавливает соединение с информационной базой и выполняет задание в рамках этого соединения. После выполнения задания рабочий процесс уведомляет планировщика об успешном или неуспешном выполнении задания.
Начиная с версии 8.3.3.641 платформы, разработчики значительно упростили работу с фоновыми заданиями в файловом варианте.
Раньше для автоматического выполнения заданий требовалось запускать отдельный, дополнительный сеанс «1С:Предприятия», используемый в качестве планировщика заданий. И в этом сеансе нужно было периодически выполнять метод встроенного языка ВыполнитьОбработкуЗаданий(). Такой подход был довольно громоздким, неудобным и сильно ограничивал использование фоновых и регламентных заданий в файловом варианте работы.
Теперь всё стало гораздо проще. Если стартует тонкий или толстый клиент, а также если у веб-сервера есть клиентские соединения, то в каждом из этих приложений автоматически запускается еще один поток с подключением к базе данных. Эти потоки занимаются тем, что выполняют фоновые и регламентные задания.
Каждое из перечисленных приложений выполняет собственные фоновые задания. Если приложение инициировало несколько фоновых заданий, то выполняются они последовательно, в порядке поступления.
Необходимо отметить, что фоновые задания - это объекты исключительно программные и их нельзя сохранить в базе данных. То есть мы можем только создать экземпляр класса, инициализировать его свойства и запустить его на выполнение.
Пример асинхронного выполнения кода в «1С:Предприятие 8»
«Писать программы, в которых результат вызова функции приходит неизвестно когда - куда сложнее, чем обычные. Вложенные вызовы, обработка ошибок, контроль над происходящим - все усложняется», - так скажут только те, кто не умеет правильно пользоваться возможностями платформы, но не мы!
Продемонстрируем всю простоту и изящество асинхронного выполнения кода в «1С:Предприятие 8»!
Шаг 1. Создадим новую ИБ для разработки конфигурации
Шаг 2. В конфигурации добавим общий модуль «АсинхронныеОбработчики»
Почему мы добавили общий модуль? Тут все просто: для выполнения асинхронных операций в «1С:Предприяте 8» применяются фоновые задания, у которых имеется свой менеджер - «МенеджерФоновыхЗадания». У этого объекта есть метод «Выполнить», с помощью которого как раз и запускается фоновое задание.
Обратимся к синтакс-помощнику.
Таким образом, нам понадобится общий модуль.
Шаг 3. В общем модуле «АиснхронныеОбработчики» добавим экспортную процедуру НашаДлительнаяОперация()
Шаг 4. Добавляем в конфигурацию обработку «АсинхроннаяКонцепцияПрограммирования» (можно создать внешнюю обработку)
На форму добавляем один реквизит:
Шаг 5. Согласно синтакс-помощнику заполняем модуль формы
Шаг 6. Запускаем и проверяем!
- если мы нажимаем на кнопку «Выполнить длительную операцию», то пользовательский интерфейс на «Длительность» секунд блокируется;
- если мы нажимаем на кнопку «Выполнить длительную операцию асинхронно», то пользовательский интерфейс не блокируется, а программный код выполняется параллельно.
В том, что программный код асинхронно выполняется, мы можем убедиться, просмотрев журнал регистрации.
Отладить программный код, который выполняется в «фоне» мы можем, если в параметрах отладки установим соответствующее свойство.
Пример асинхронного выполнения кода в «1С:Предприятие 8» с использование БСП
Пример реализации асинхронной концепции программирования в «1С:Предприятие 8» в БСП рассмотрим на примере обработки «Текущие дела».
Логика следующая: во время запуска программы инициализируется рабочая область начальной страницы, куда можно вывести форму обработки «Текущие дела». Эта форма заполняется текущими делами пользователя, а чтобы ее заполнить необходимо время. Если бы у разработчиков не было возможности асинхронно выполнять код, то на все время заполнения формы обработки пользовательский интерфейс был бы заблокирован!
Проанализируем программный код формы.
Событие формы «ПриСозданииНаСервере» вызывает процедуру «ЗапуститьФоновоеЗадание» - это то, что нам и нужно.
Не отвлекаясь на нюансы, анализируем данную процедуру
И здесь мы видим, что используется менеджер фоновых заданий и его метод «Выполнить». Отметить, что разработчики сохраняют уникальный идентификатор фонового задания.
И Что же дальше? А дальше нам необходимо отловить момент выполнения задания.
Для этого разработчики применяют метод ПодключитьОбработчикОжидания(<ИмяПроцедуры>, <Интервал>, <Однократно>).
В подключаемой процедуре Подключаемый_ПроверитьВыполнениеЗадания() разработчики вызывают функцию ЗаданиеВыполнено(ИдентификаторЗадания)
Данная функция по идентификатору проверяет выполнения фонового задания.
Необходимо отметить, что в БСП разработаны общие модули поддержки работы длительных серверных операций.
Таким образом, асинхронная концепция программирования в «1С:Предприятие 8» незначительно увеличивает трудоемкость решения задач для разработчика, но заметно улучшает функциональность программы с точки зрения пользователя.
В 1С есть возможность использования встроенных асинхронных вызовов с помощью описания оповещения. Мне необходимо "обернуть" несколько асинхронных вызовов в один свой, так чтобы со стороны основного кода выполнялся всего один такой вызов.
Можно ли создать свои асинхронные методы и как?
Доброго времени суток, платформа «1С:Предприятие 8» не дает возможности реализовывать свои асинхронные процедуры и функции. Реализовать асинхронную обработку ("обернуть"), все-таки, возможность есть, с помощью процедуры:
Этот метод используется для того, чтобы выполнить процедуру обработчика оповещения. Чтобы указать на этот обработчик, в метод передаётся описание оповещения.
Этот метод требуется в сложных «многоуровневых» алгоритмах асинхронных вызовов, так как описание оповещения может быть сконструировано в начале алгоритма, а реальное использование этого обработчика может понадобиться через несколько вложенных процедур. Пример:
Вопрос во вложенной процедуре, после которой есть код
Рассмотрим более сложный случай, когда после вызова вложенной функции выполнятся некоторый код. Например, так:
Казалось бы, следуя рекомендациям, надо просто заменить вложенную процедуру двумя процедурами:
Однако в этом случае алгоритм, следующий за вызовом вложенной процедуры, будет выполнен ещё до того, как пользователь ответит на вопрос. Ведь, как мы знаем, исполнение кода не останавливается после выполнения блокирующего метода (Сравнение модального и немодального режимов работы):
Поэтому в такой ситуации нужно не только использовать блокирующий метод с вызовом оповещения, но ещё и выполнять асинхронный вызов самой вложенной процедуры, также используя оповещение:
Здесь во вложенную процедуру мы сразу передаём описание оповещения, в котором содержится тот код, который должен быть выполнен после вложенной процедуры (последняя процедура). Вызывая блокирующий метод, мы передаём ему «его» описание оповещения (ВложеннаяПроцедураЗавершение), а также, через дополнительные параметры, то описание оповещения, которое нужно будет выполнить после того, как будут обработаны интерактивные действия пользователя (ОбработкаКомандыЗавершение).
P.S. Необходимо помнить, что при работе с синхронными вызовами значения передаются по Ссылке (в синхронные процедуры и функции), а при асинхронных вызовах по Значению . Пример:
Вопрос в обработчике формы ПередЗакрытием
Особенность диалога с пользователем в этом (и многих других) обработчиках заключается в том, что в зависимости от реакции пользователя принимается решение: продолжать дальнейшие действия, или отказаться от них. Для этого используется параметр процедуры Отказ. При одном ответе пользователя мы отказываемся от продолжения (Отказ = Истина). При другом ответе пользователя - продолжаем дальнейшие действия.
В данном случае сложность заключается в том, что ответ пользователя мы узнаем уже после того, как выйдем из контекста этого обработчика. В процедуре, обрабатывающей оповещение. А параметр Отказ нужно установить именно в этом обработчике.
Поэтому мы действуем в два приёма:
В первый раз безусловно отменяем дальнейшие действия (Отказ = Истина) и выводим вопрос пользователю; В обработчике оповещения, в зависимости от реакции пользователя, либо снова программно закрываем форму, либо ничего не делаем. Проблема заключается в том, что обработчик ПередЗакрытием будет выполнен два раза. И чтобы отличить первое его выполнение от второго (когда ответ пользователя уже известен) мы используем клиентскую переменную ВыполняетсяЗакрытие в качестве флага.
В первый проход её значение равно Ложь, и это значит, что нужно отказаться от закрытия и задать вопрос. Во второй проход её значение равно Истина, и это значит, что вопрос задавать не надо:
В рамках одного сеанса работы в 1С выполнение встроенного языка выполняется последовательно, иначе говоря синхронно. Выполнение происходит в одном потоке, синхронные методы блокируют основной поток до окончания своего выполнения.
Пример синхронного выполнения:
Асинхронные методы не блокируют основной поток. Асинхронность в 1С реализуется с помощью очереди асинхронных задач. Основной поток выполняет задачи из этой очереди, как только сможет это сделать. Важно понимать, что асинхронность это не многопоточность. Многопоточность в 1С реализуется с помощью других механизмов.
Пример асинхронного выполнения в 1С:
Асинхронную технику можно использовать только на клиенте для реализации следующих задач:
- Работа с блокирующими окнами
- Работа с расширением работы с файлами
- Работа с расширением криптографии
- Работа с внешними компонентами
В нашем примере использовать асинхронность через Обещания, но 1С поддерживает два варианта асинхронности:
- Асинхронность через обратные вызовы (ОписаниеОповещения)
- Асинхронность через Обещания
ОписаниеОповещения
Асинхронность через обратные вызовы реализована в 1С с помощью объекта встроенного языка ОписаниеОповещения. Сам термин обратный вызов (call back) называется так, потому что мы сначала передаем ссылку на метод в асинхронную процедуру или функцию, а после выполнения асинхронной процедуры выполняется обратный вызов переданного метода.
Процедуры обратного вызова могут быть только на клиенте, обязательно со словом Экспорт, только в модуле формы, модуле команды или в общем модуле.
ОбратныйВызов = Новый ОписаниеОповещения ( "ОбратныйВызов" , ЭтотОбъект ) ; //данная процедура будет вызвана после того как в предупреждении нажмут "ОК" Процедура ОбратныйВызов ( ДополнительныеПараметры ) Экспорт
Асинхронность через обещания
Обещание
Объект обещание может иметь 3 состояния:
Оператор Ждать
Оператор Ждать позволяет получить результат функции из обещания. Параметром данного оператора может быть только объект с типом обещание. Оператор Ждать можно использовать только в процедурах и функциях, которые отмечены модификатором Асинх. А также у собственных асинхронных функций, которые возвращают обещание тоже нужно указывать модификатор Асинх.
Читайте также: