ВызватьПаузу: измерить короткую паузу в собственном фоновом задании

Учебные задачи

Кнопка обычной формы запускает собственную серверную процедуру как фоновое задание. Процедура делает паузу 1500 миллисекунд между двумя настоящими отсчетами UTC, отправляет одно сообщение с измерением; форма проверяет паспорт и успешное завершение задания, затем показывает именно полученный текст.

Где и как запускать

Сервер: собственный неглобальный общий модуль, исполнение только штатным фоновым заданием. Запуск и ожидание — собственная обычная форма толстого управляемого клиента 8.5.1.1343.

Подготовка

  1. Это будущий опыт только в НОВОЙ пустой файловой базе на своей отдельной Windows VM. Сейчас 1С и задания не запускались. Создайте базу C:\1c-study\OwnedPause85_bf8a7d85\IB, не используйте рабочую конфигурацию и внешнее COM-соединение. В списке баз явно зарегистрируйте эту папку: код принимает только строку File="C:\1c-study\OwnedPause85_bf8a7d85\IB";. Другой формат — остановка до запуска, а не разрешение подменить путь.

  2. Имя новой конфигурации = УчебнаяФоноваяПауза85, Версия = bf8a7d85-ff04-46ab-9b58-6493e742adcc. Платформа = 8.5.1.1343, русский встроенный язык, Основной режим запуска = Управляемое приложение, интерфейс Такси, Использовать обычные формы в управляемом приложении = Истина, совместимость = НеИспользовать. Это маркеры подготовки, а не доказательство владения. Если редактор скрывает обычные формы, Сервис → Параметры → Общие: выберите вид редактирования для обычного приложения; это видимость редактора, не изменение основного режима запуска конфигурации.

  3. Один собственный учебный пользователь, одно клиентское подключение, никаких регламентных заданий, расширений, подписок, других модулей и производственных данных. Для этого отдельного стенда вручную создайте свою учебную роль с полными правами и назначьте ее своему пользователю; это не обещание минимальных прав для рабочей базы. До опыта владелец отдельно обеспечивает лицензию 1С и доступность выполнения фоновых заданий.

  4. Общие → Общие модули: создайте только УчебнаяПауза85. Глобальный = Нет, Сервер = Да, Клиент (обычное приложение) = Нет, Клиент (управляемое приложение) = Нет, Внешнее соединение = Нет, Вызов сервера = Нет, Привилегированный = Нет, Повторное использование возвращаемых значений = НеИспользовать. Основной код карточки вставьте ЦЕЛИКОМ в этот модуль. Измерить85 экспортирована для штатного запуска менеджером, а не прямого вызова с клиента.

  5. Общие → Общие формы: создайте только обычную форму Пауза85, не управляемую. В ее реквизитах задайте Согласие85 / Булево, Остановка85 / Булево и Результат85 / Строка неограниченной длины. Начальные значения в редакторе не требуются: фактическая Остановка85 на новом экземпляре должна быть Ложь, код не сбрасывает ее. Пользователь сам отмечает Согласие85.

  6. На вкладке Диалог добавьте флажок для Согласие85 и многострочное поле Результат85 только для просмотра, связав их с одноименными реквизитами. Остановка85 в диалог не выводится. Добавьте обычную кнопку Запустить85: ее штатное событие Нажатие свяжите с Запустить85 без параметров. Это Кнопка.Нажатие(), не команда управляемой формы с параметром Команда. В модуль формы вставьте целиком отдельный блок Пауза85 ниже.

  7. Конфигурация → Открыть модуль управляемого приложения: вставьте отдельный блок УправляемоеПриложение ниже. Штатный ПриНачалеРаботыСистемы() получает собственную именованную форму с настоящим новым ключом уникальности и открывает ее. Обработчики вручную не вызывайте.

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

  9. Согласие тратится и Остановка85 устанавливается ДО создания ключа и запуска. Ни успешное завершение, ни ошибка не разрешают повтор в этой форме. При ошибке или истечении ожидания задание может оставаться активным; код его не отменяет, не опрашивает, не запускает повторно и не чистит историю. STOP не означает отмену или откат.

Процедура Измерить85(Интервал, Ключ) Экспорт
#Если Сервер Тогда
    Система = Новый СистемнаяИнформация;
    Если ТипЗнч(Система) <> Тип("СистемнаяИнформация") Тогда
        ВызватьИсключение "Нужна платформа 8.5.1.1343";
    КонецЕсли;
    Если ТипЗнч(Интервал) <> Тип("Число") Или Интервал <> 1500
        Или ТипЗнч(Ключ) <> Тип("Строка") Или Ключ = "" Тогда
        ВызватьИсключение "Нужны свой ключ и учебный интервал 1500 мс";
    КонецЕсли;
    Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
    Если ТипЗнч(Начало) <> Тип("Число") Тогда
        ВызватьИсключение "Не получен числовой отсчет UTC";
    КонецЕсли;
    ВызватьПаузу(Интервал);
    Конец = ТекущаяУниверсальнаяДатаВМиллисекундах();
    Если ТипЗнч(Конец) <> Тип("Число") Тогда
        ВызватьИсключение "Не получен второй числовой отсчет UTC";
    КонецЕсли;
    Разность = Конец - Начало;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Пауза85|" + Ключ + "|интервал, мс: " + Строка(Интервал)
        + "; UTC до: " + Строка(Начало) + "; UTC после: " + Строка(Конец)
        + "; разность, мс: " + Строка(Разность);
    Если Разность < 0 Тогда
        Сообщение.Текст = Сообщение.Текст + "; часы сместились назад: это не ошибка паузы";
    КонецЕсли;
    Сообщение.Сообщить();
#Иначе
    ВызватьИсключение "Этот модуль предназначен только для своего фонового задания";
#КонецЕсли
КонецПроцедуры
Настоящая кнопка обычной формы: один запуск, ограниченное ожидание и полученный текст

Общие → Общие формы → Пауза85 → Модуль

Толстый управляемый клиент, собственная обычная Форма

Процедура Запустить85()
#Если ТолстыйКлиентУправляемоеПриложение Тогда
    Попытка
        Если ТипЗнч(Остановка85) <> Тип("Булево") Или Остановка85 <> Ложь
            Или ТипЗнч(Согласие85) <> Тип("Булево") Или Согласие85 <> Истина
            Или ТипЗнч(Результат85) <> Тип("Строка") Или ТипЗнч(ЭтаФорма) <> Тип("Форма") Тогда
            ВызватьИсключение "Нужны своя новая обычная форма и явно отмеченное согласие";
        КонецЕсли;
        Система = Новый СистемнаяИнформация;
        Соединение = СтрокаСоединенияИнформационнойБазы();
        Если ТипЗнч(Система) <> Тип("СистемнаяИнформация") Или ТипЗнч(Соединение) <> Тип("Строка") Или Соединение <> "File=""C:\1c-study\OwnedPause85_bf8a7d85\IB"";" Тогда
            ВызватьИсключение "Не своя новая файловая база на платформе 8.5.1.1343";
        КонецЕсли;
        Если Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении <> Истина Тогда
            ВызватьИсключение "Не своя точная подготовка конфигурации";
        КонецЕсли;
        Согласие85 = Ложь;
        Остановка85 = Истина;
        Результат85 = "Попытка потрачена. Успешный результат еще не получен.";
        ИдентификаторКлюча = Новый УникальныйИдентификатор();
        Если ТипЗнч(ИдентификаторКлюча) <> Тип("УникальныйИдентификатор") Тогда
            ВызватьИсключение "Не получен настоящий новый идентификатор";
        КонецЕсли;
        Ключ = Строка(ИдентификаторКлюча);
        Параметры = Новый Массив;
        Параметры.Добавить(1500);
        Параметры.Добавить(Ключ);
        Менеджер = ФоновыеЗадания;
        Если ТипЗнч(Менеджер) <> Тип("МенеджерФоновыхЗаданий") Тогда
            ВызватьИсключение "Не получен штатный менеджер заданий";
        КонецЕсли;
        Задание = Менеджер.Выполнить("УчебнаяПауза85.Измерить85", Параметры, Ключ, "Собственная учебная пауза 1500 мс");
        Если ТипЗнч(Задание) <> Тип("ФоновоеЗадание") Тогда
            ВызватьИсключение "Не получено собственное фоновое задание";
        КонецЕсли;
        Идентификатор = Задание.УникальныйИдентификатор;
        Если ТипЗнч(Идентификатор) <> Тип("УникальныйИдентификатор")
            Или ТипЗнч(Задание.Ключ) <> Тип("Строка") Или Задание.Ключ <> Ключ
            Или ТипЗнч(Задание.ИмяМетода) <> Тип("Строка") Или Задание.ИмяМетода <> "УчебнаяПауза85.Измерить85" Тогда
            ВызватьИсключение "Паспорт запущенного задания не совпал";
        КонецЕсли;
        Обновленное = Задание.ОжидатьЗавершенияВыполнения(10);
        Если ТипЗнч(Обновленное) <> Тип("ФоновоеЗадание")
            Или ТипЗнч(Обновленное.УникальныйИдентификатор) <> Тип("УникальныйИдентификатор")
            Или Обновленное.УникальныйИдентификатор <> Идентификатор
            Или ТипЗнч(Обновленное.Ключ) <> Тип("Строка") Или Обновленное.Ключ <> Ключ
            Или ТипЗнч(Обновленное.ИмяМетода) <> Тип("Строка")
            Или Обновленное.ИмяМетода <> "УчебнаяПауза85.Измерить85"
            Или ТипЗнч(Обновленное.Состояние) <> Тип("СостояниеФоновогоЗадания")
            Или Обновленное.Состояние <> СостояниеФоновогоЗадания.Завершено Тогда
            ВызватьИсключение "Успешное завершение собственного задания не подтверждено";
        КонецЕсли;
        Сообщения = Обновленное.ПолучитьСообщенияПользователю(Ложь);
        Если ТипЗнч(Сообщения) <> Тип("ФиксированныйМассив") Или Сообщения.Количество() <> 1 Тогда
            ВызватьИсключение "Не получено ровно одно собственное сообщение";
        КонецЕсли;
        Для Каждого Сообщение Из Сообщения Цикл
            Если ТипЗнч(Сообщение) <> Тип("СообщениеПользователю")
                Или ТипЗнч(Сообщение.Текст) <> Тип("Строка") Тогда
                ВызватьИсключение "Получен не учебный текст сообщения";
            КонецЕсли;
            СвоеСообщение = СтрНачинаетсяС(Сообщение.Текст, "Пауза85|" + Ключ + "|интервал, мс: ");
            Если ТипЗнч(СвоеСообщение) <> Тип("Булево") Или СвоеСообщение <> Истина Тогда
                ВызватьИсключение "Сообщение не относится к своему ключу и измерению";
            КонецЕсли;
            Результат85 = Сообщение.Текст;
        КонецЦикла;
    Исключение
        Согласие85 = Ложь;
        Остановка85 = Истина;
        Результат85 = "STOP: успешный результат не подтвержден; задание могло продолжить работу. Повтора и отмены нет.";
        ВызватьИсключение;
    КонецПопытки;
#Иначе
    ВызватьИсключение "Нужен толстый управляемый клиент и собственная обычная форма";
#КонецЕсли
КонецПроцедуры
Штатно открыть собственную обычную форму

Конфигурация → Модуль управляемого приложения

Толстый управляемый клиент

Процедура ПриНачалеРаботыСистемы()
#Если ТолстыйКлиентУправляемоеПриложение Тогда
    Если Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении <> Истина Тогда
        ВызватьИсключение "Не подготовлено собственное учебное приложение";
    КонецЕсли;
    Форма = ПолучитьОбщуюФорму("Пауза85", , Новый УникальныйИдентификатор());
    Если ТипЗнч(Форма) <> Тип("Форма") Тогда
        ВызватьИсключение "Получена не своя обычная форма";
    КонецЕсли;
    Форма.Открыть();
#Иначе
    ВызватьИсключение "Запустите собственный толстый клиент в управляемом режиме";
#КонецЕсли
КонецПроцедуры

Разбор по шагам

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

  2. Кнопка запрещает повтор до запуска, создает настоящий UUID и строковый ключ. Массив передает 1500 и этот ключ в точном порядке двух параметров экспортированной серверной процедуры. Выполнить возвращает объект задания, а не результат измерения.

  3. Только внутри задания считываются UTC до и после ВызватьПаузу(Интервал). 1500 — целое неотрицательное число миллисекунд. Разность этих двух фактических чисел включается в одно сообщение вместе с ключом и исходным интервалом.

  4. Форма ровно один раз вызывает ОжидатьЗавершенияВыполнения(10): здесь 10 означает секунды. Присвоенный возврат — обновленный объект задания. Проверяются настоящий UUID, ключ, имя метода и состояние Завершено; возврат из ожидания сам по себе не означает успех.

  5. Только затем читаются сообщения обновленного задания без удаления. Фактически требуется ФиксированныйМассив ровно из одного СообщениеПользователю со строковым текстом и префиксом своего ключа/интервала. Полученный текст попадает в свое поле, без выдуманного готового числа.

Как проверить результат

  1. До команды согласие должно быть явно отмечено; после команды оно снято. Остановка85 остается Истина и на положительном пути. Повтор в том же экземпляре формы запрещен.

  2. Положительный результат начинается Пауза85|, содержит фактический ключ, интервал 1500, два числовых отсчета UTC и их разность в миллисекундах. Это ожидаемое ручное наблюдение в будущем стенде, не результат уже выполненного опыта.

  3. UUID обновленного задания совпадает с удержанным UUID запущенного. Ключ и полное имя УчебнаяПауза85.Измерить85 совпадают; состояние именно Завершено. Ошибка, отмена или все еще активное задание — STOP, не успешный пример.

  4. Ровно одно собственное сообщение показано в Результат85. Метод вызван с Ложь: сообщения не удаляются. Их сохранение платформой и история заданий не выдаются за полностью бесписьменную операцию.

  5. UTC — обычные часы, не монотонный секундомер. Разность может отличаться от 1500 и при коррекции часов стать отрицательной: в этом случае текст объясняет сдвиг часов, а не объявляет ошибку паузы.

Ожидаемый результат

Ожидаемый результат будущего опыта: одно успешно завершенное собственное фоновое задание, проверенный паспорт и полученный из него текст настоящего измерения в своей форме. Точное время, успешное завершение за 10 секунд и точность планировщика не гарантируются. В 1С код не запускался.

На что обратить внимание

  1. Доступность ВызватьПаузу в толстом клиенте не разрешает вызывать его прямо из кнопки или обычного клиентского обращения на сервер. Здесь допустимый источник исполнения — штатно созданное фоновое задание.

  2. В файловой базе одновременно исполняется только одно фоновое задание. Другие задания могут задержать запуск; выполнение через внешнее COM-соединение для этого опыта не подходит. Не заменяйте создание задания вызовом Измерить85 из формы.

  3. Значение 1500 у ВызватьПаузу измеряется в миллисекундах; 10 у ОжидатьЗавершенияВыполнения — в секундах. Старый ОжидатьЗавершения без ограничения не используется. Нет цикла опроса, повторного запуска и ожидания из другого фонового задания.

  4. Истекшее ожидание может вернуть еще активный объект. Исключение в задании не превращается автоматически в успешный возврат результата. Сначала проверяется фактическое состояние обновленного объекта, только потом его сообщения.

  5. После ошибки нет отмены, удаления сообщений, повторов, отката или обращения к менеджеру для выяснения состояния. Пользователь видит STOP с честным предупреждением о неизвестном результате; фоновое задание могло продолжить работу.

  6. УстановитьЗапретЗасыпанияКомпьютера не относится к этому desktop-опыту и не вызывается. Отрицательная разность UTC не доказывает неисправность паузы; точные 1500, монотонность и нижняя граница замера не обещаются.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.