У цій статті я покажу свою реалізацію асинхронних викликів серверних функцій і процедур
Основна перевага асинхронних викликів перед синхронними в тому, що вони не блокують призначений для користувача інтерфейс. Якщо ви синхронно запускаєте процедуру або функцію, яка тривало виконує якісь дії, то ваш призначений для користувача інтерфейс на цей час буде недоступний.
Можна сказати, що побудова звіту в фоновому режимі (СкомпоноватьРезультат (РежімКомпоновкіРезультата.Фоновий)) і є асинхронний виклик. Правда тут треба зробити застереження, що все-таки це лише емуляція асинхронного виклику, як і реалізація, яку я покажу.
1. Звичайне і кероване додатки
2. Клієнт-серверний і файловий режим
3. Асинхронне виконання серверних процедур і функцій
4. Отримання повертається функцією значення
5. Отримання опису сталася помилки
6. Скасування асинхронного виклику
7. Стеження за завершенням асинхронного виклику
8. Спостереження за ходом виконання асинхронного виклику
Вимоги до асинхронно викликаються функцій і процедур
Асинхронно викликаються функції і процедури повинні бути експортними, і можуть знаходитися в наступних модулях:
- Модулі менеджерів об'єктів
- Глобальні і неглобальні серверні загальні модулі
Параметри в цих функціях і процедурах повинні мати можливість передаватися з клієнта на сервер. Значення, що повертаються в цих функціях повинні мати можливість передаватися з сервера на клієнт.
За фактом можна сказати, що вимоги такі ж, як і до функцій і процедур, які перебувають в загальних серверних модулях з ознакою ВизовСервера.
Загальний модуль АсінхронниеВизови
У цьому модулі знаходяться процедури і функції програмного інтерфейсу асинхронних викликів. Тільки з цим модулем вам доведеться працювати при здійсненні асинхронних викликів.
Програмний інтерфейс складається з наступних процедур та функцій:
Навколо цієї структури і відбуваються всі дії - в ній зберігається вся інформація про асинхронному виклику.
Постійні властивості:
Ідентифікатор - ідентифікатор асинхронного виклику (за фактом ідентифікатор фонового завдання)
ІмяФункцііІліПроцедури - повне ім'я серверної функції або процедури
ЕтоФункція - ознака того, що запускали функцію і буде повертається значення
Параметри - масив параметрів, який ми передали при асинхронному виконанні функції або процедури
Форма - форма, в модулі якої знаходяться процедури обробники
ІмяОбработчікаЗавершенія - ім'я експортної процедури знаходиться в модулі форми, яка буде обробляти завершення виконання асинхронного виклику
ІмяОбработчікаХодаВиполненія - ім'я експортної процедури знаходиться в модулі форми, яка буде обробляти хід виконання асинхронного виклику
АвтоотменаЧерез - кількість секунд, через яке необхідно автоматично скасувати асинхронний виклик
НачатВ - час початку асинхронного виклику
Контекст - довільна додаткова інформація, яка може бути пов'язана з асинхронним викликом
Змінні властивості:
Стан - стан асинхронного виклику (Активний, Завершено, Скасовано, ЗавершенСОшібкой)
ВозвращенноеЗначеніе - значення поверненню функцією (для процедур цієї властивості немає)
ЗначеніеХодаВиполненія - значення ходу виконання, наприклад, відсоток завершення
СообщеніяХодаВиполненія - всі повідомлення, які передавала асинхронно викликана функція або процедура
ОпісаніеОшібкі - опис помилки що сталася при асинхронному виклику
Вам не слід самим змінювати значення в цій структурі.
Асинхронний виклик процедури або функції
Асинхронно викликати процедуру або функцію можна тільки з клієнта. Для цього використовуються дві функції: ВизиватьФункцію і ВизиватьПроцедуру. Обидві вони повертають структуру АсінхроннийВизов. але ви можете не обробляти результат, який вони повертають, якщо використовуєте обробники або не хочете стежити за долею виклику.
Ось найпростіший асинхронний виклик:
Якщо процедура або функція має входять параметри, то такий виклик буде виглядати так:
Скасування асинхронного виклику
Асинхронний виклик можна скасувати вручну, приблизно так:
Як параметр можна передати структуру АсінхроннийВизов, унікальний ідентифікатор виклику, рядок містить унікальний ідентифікатор виклику або Масив, який може містити всі раніше перераховане.
Можна скасувати відразу все асинхронні виклики, ось так:
При цьому можна сказати, що в обох прикладах вище, сам скасовує виклик є асинхронним, тобто після його завершення стан асинхронного виклику не зміниться відразу.
Також асинхронний виклик можна скасувати автоматично після закінчення заданого часу, приблизно так:
Стеження за завершенням асинхронного виклику
Для того, щоб відстежити момент, коли асинхронний виклик буде завершено (нормально, з помилкою або буде скасований) вам необхідно зробити наступне.
По-перше, ви повинні реалізувати процедуру обробник завершення асинхронного виклику.
Для звичайної форми і асинхронно викликаної процедури обробник буде виглядати так:
Для керованої форми і асинхронно викликаної функції обробник буде виглядати так:
Ім'я обробника ви вибираєте самі.
По-друге, ви повинні при асинхронному виклику передати в параметрах викликає форму і ім'я обробника завершення з модуля цієї форми, приблизно так:
Коли асинхронний виклик завершиться (нормально, з помилкою або буде скасований), то буде викликаний наш обробник завершення.
Ви можете дізнатися про завершення асинхронного виклику без підключення обробника завершення. Для цього ви повинні зберегти структуру АсінхроннийВизов, яку повертають функції ВизватьФункцію і ВизватьПроцедуру, і періодично або після натискання кнопки перевіряти значення властивості Стан.
Стеження за ходом виконання асинхронного виклику
Асинхронний виклик може виконуватися довго і іноді хотілося б розуміти скільки вже виконано, що саме вже виконано, ну і так далі.
Для вирішення цього завдання я ввів два терміни: значення ходу виконання і повідомлення ходу виконання.
Значення ходу виконання - це значення, яке характеризує завершеність асинхронного виклику. Це може бути відсоток виконання, кількість створених об'єктів. Причому не обов'язково це має бути число, це може бути структура, яка містить кілька значень і не обов'язково числових.
Повідомлення ходу виконання - це повідомлення, які можуть допомогти в розумінні того, що вже виконано. Це може бути логирование асинхронного виклику або якісь важливі повідомлення для користувача. Причому не обов'язково це має бути рядок, це може бути структура яка містить кілька значень і не обов'язково строкових.
Значення і повідомлення ходу виконання - це різні речі. Значення в кожен момент тільки одне, а ось повідомлень може бути багато.
Для того, щоб можна було обробляти значення і повідомлення ходу виконання, функція або процедура, що викликається асинхронно, повинна їх передавати спеціальним чином. Для цього реалізовані 2 процедури ОбновітьЗначеніеХодаВиполненія і ДобавітьСообщеніеХодаВиполненія.
Приблизно ось так їх можна використовувати:
Отже, якщо ваша функція або процедура, що викликається асинхронно, оновлює значення або додає повідомлення ходу виконання, то ви можете їх відстежувати. Для цього потрібно зробити наступне.
По-перше, вам необхідно реалізувати обробник ходу виконання асинхронного виклику. Для звичайної форми він буде виглядати так:
Ім'я обробника ви вибираєте самі.
По-друге, ви повинні при асинхронному виклику передати в параметрах викликає форму і ім'я обробника ходу виконання з модуля цієї форми, приблизно так:
Оброблювач ходу виконання буде викликатися тоді, коли оновилося значення ходу виконання або з'явилися нові повідомлення ходу виконання.
Ви можете дізнатися про хід виконання асинхронного виклику без підключення обробника ходу виконання. Для цього ви повинні зберегти структуру АсінхроннийВизов, яку повертають функції ВизватьФункцію і ВизватьПроцедуру, і періодично або після натискання кнопки перевіряти значення властивостей ЗначеніеХодаВиполненія і СообщеніяХодаВиполненія. Якщо ви хочете бачити тільки нові повідомлення, ще не оброблені вами, то ви повинні очищати їх.
У демонстраційній конфігурації АсінхронниеВизови.cf ви знайдете приклад для звичайного застосування.
І для керованого застосування.
Поексперементіруйте - це цікаво.
Можна сказати, що вся реалізація будується на наступному:
- Фонові завдання і метод ПолучітьСообщеніяПользователю
- Глобальний обробник очікування
- Серіалізация / десеріалізацію за допомогою ЗначеніеВСтрокуВнутр / ЗначеніеІзСтрокіВнутр
Більш детально ви завжди можете подивитися реалізацію в АсінхронниеВизови.cf
Для впровадження в конфігурацію необхідно перенести 4 загальних модуля:
А так же додати в модулі керованого і звичайного додатків експортну змінну НезавершенниеАсінхронниеВизови.
Сподіваюся, описаний в статті матеріал буде вам корисний.
Дякуємо за увагу.