К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как сделать паузу в 1С: рабочие способы задержки выполнения кода

Как сделать паузу в 1С: почему нет функции Sleep, как реализовать задержку через цикл, COM-объект и фоновые задания, примеры кода и типичные ошибки.

Разработчики, переходящие на 1С с других языков, первым делом ищут аналог функции Sleep или Delay — и не находят. Во встроенном языке 1С действительно нет штатной команды «подождать N секунд», и это осознанное архитектурное решение платформы: «замороженный» клиентский сеанс блокирует интерфейс пользователя и держит соединение с сервером. Тем не менее задачи, где пауза нужна, существуют: ожидание ответа внешнего сервиса, повторная попытка при ошибке, задержка между обращениями к оборудованию.

На практике применяют несколько обходных приёмов: пустой цикл по текущей дате, вызов метода Sleep через COM-объект Windows Script Host, ожидание завершения фонового задания и асинхронные механизмы платформы. Каждый способ имеет свои ограничения: одни работают только на клиенте, другие недоступны в веб-клиенте, третьи требуют аккуратной обработки ошибок.

Ниже разобраны рабочие варианты с примерами кода, условиями выбора и типичными ошибками. Материал ориентирован на управляемые формы и платформу 8.3, но отдельные приёмы применимы и в обычном приложении.

Почему в 1С нет штатной функции Sleep

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

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

Пауза циклом по текущей дате

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

Процедура Пауза(Секунды) Экспорт

ВремяОкончания = ТекущаяДата() + Секунды;

Пока ТекущаяДата() < ВремяОкончания Цикл

// пустой цикл ожидания

КонецЦикла;

КонецПроцедуры

Обратите внимание на точность: функция ТекущаяДата() возвращает время с точностью до секунды, поэтому для дробных задержек нужна ТекущаяУниверсальнаяДатаВМиллисекундах(). Также помните, что на клиенте ТекущаяДата() возвращает время компьютера пользователя, а на сервере — время сервера; при небольших паузах это несущественно.

Минус способа — активное ожидание: процессор в течение паузы выполняет бесполезные итерации. Для задержки в пару секунд это незаметно, но паузы в десятки секунд так организовывать не стоит.

Пауза в миллисекундах

Если нужна задержка короче секунды, используйте миллисекундный вариант:

Процедура ПаузаМс(Миллисекунды) Экспорт

Окончание = ТекущаяУниверсальнаяДатаВМиллисекундах() + Миллисекунды;

Пока ТекущаяУниверсальнаяДатаВМиллисекундах() < Окончание Цикл

КонецЦикла;

КонецПроцедуры

Пауза через COM-объект WScript.Shell

Классический приём — вызвать настоящий Sleep операционной системы через Windows Script Host. Метод Sleep не грузит процессор, так как поток реально «засыпает»:

Попытка

Оболочка = Новый COMОбъект("WScript.Shell");

Оболочка.Run("powershell -command ""Start-Sleep -Seconds 5""", 0, Истина);

Исключение

// COM недоступен — запасной вариант циклом

КонецПопытки;

Часто встречается и другой вариант — через объект WScript.Network или прямой вызов ping с таймаутом, но принцип один: задержку выполняет внешний процесс. У способа есть жёсткие ограничения: он работает только под Windows, только там, где разрешено создание COM-объектов (на клиенте — в тонком и толстом клиенте, на сервере — если учётной записи сервера 1С это позволяет), и недоступен в веб-клиенте и на Linux-сервере.

Ожидание через фоновые задания

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

На сервере можно дождаться завершения задания методом ОжидатьЗавершенияВыполнения(), передав массив заданий и, при необходимости, таймаут в секундах:

Задания = Новый Массив;

Задания.Добавить(ФоновыеЗадания.Выполнить("ОбщийМодуль.ДлительнаяОперация", Параметры));

// ждём не более 60 секунд

ФоновыеЗадания.ОжидатьЗавершенияВыполнения(Задания, 60);

На клиенте вместо ожидания используют механизм длительных операций из БСП или собственную схему с подключаемым обработчиком ожидания: форма остаётся рабочей, а обработчик раз в несколько секунд проверяет готовность результата. Это единственный корректный способ «ждать» в веб-клиенте.

Подключаемый обработчик ожидания как замена паузы

Метод ПодключитьОбработчикОжидания() позволяет выполнять процедуру формы с заданным интервалом — фактически это неблокирующий аналог таймера. Интервал задаётся в секундах, минимальное разумное значение — около секунды; слишком частые вызовы создают лишнюю нагрузку на клиент-серверное взаимодействие.

Сравнение вариантов

Цикл по ТекущаяДата()

Работает везде, включая сервер и Linux, но грузит процессор и блокирует сеанс. Подходит для пауз до нескольких секунд.

COM WScript.Shell

Поток реально спит, процессор не нагружается, но только Windows и только там, где разрешены COM-объекты. Не работает в веб-клиенте.

Фоновые задания и обработчик ожидания

Единственный правильный вариант для длительных ожиданий и веб-клиента. Требует перестройки логики на асинхронную.

Как выбрать способ под свою задачу

Выбор определяется тремя факторами: где выполняется код (клиент, сервер, веб-клиент), как долго нужно ждать и что именно вы ждёте — просто время или результат операции.

Маршрут решения

Как выбрать действие

Нужна короткая задержка 1–5 секунд в серверном коде или общем модулеИспользуйте цикл по ТекущаяДата() — он переносим и не требует внешних компонент
Пауза нужна на тонком клиенте под Windows и процессор критиченВызовите Sleep через COM WScript.Shell с обработкой исключения и запасным циклом
Код должен работать в веб-клиентеБлокирующие паузы исключены — используйте ПодключитьОбработчикОжидания и фоновые задания
Вы ждёте результат длительной операции, а не просто времяЗапустите фоновое задание и ожидайте его завершения, а не делайте паузу «на глаз»

Отдельный случай — паузы в обменах с внешними API, когда сервис просит не чаще определённого интервала. Здесь надёжнее не «спать» в цикле, а хранить время последнего обращения и перед каждым запросом проверять, прошло ли достаточно времени. Такой подход не блокирует сеанс и корректно работает при любом количестве пользователей.

Проверка результата и типичные ошибки

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

Контрольные точки

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

Фактическая длительность паузы
Норма

Отклонение от заданной — доли секунды для цикла, до секунды для COM-вызова

Тревожный признак

Пауза заметно длиннее заданной или не выполняется вовсе

Поведение формы во время паузы
Норма

Для короткой паузы — кратковременное «подвисание», для длительной — индикатор и рабочий интерфейс

Тревожный признак

Форма «замерзает» на десятки секунд без обратной связи

Журнал регистрации
Норма

Нет ошибок создания COM-объектов и таймаутов

Тревожный признак

Ошибки «Ошибка создания объекта» или «Превышен таймаут»

Типичные ошибки
01
{'name': 'Пауза вместо ожидания результата', 'text': 'Разработчик ставит паузу 10 секунд «чтобы данные успели записаться», хотя нужно дождаться завершения конкретного задания. Итог — код то работает, то нет, в зависимости от нагрузки.'}
02
{'name': 'Цикл ожидания в длительной паузе', 'text': 'Активный цикл на 30–60 секунд грузит ядро процессора и блокирует сеанс, в клиент-серверном режиме это заметно другим пользователям.'}
03
{'name': 'COM-вызов без обработки исключений', 'text': 'Код, проверенный на Windows-клиенте, падает с ошибкой на Linux-сервере или в веб-клиенте в самый неподходящий момент.'}
04
{'name': 'Пауза внутри транзакции', 'text': 'Ожидание при открытой транзакции удерживает блокировки данных и провоцирует взаимоблокировки и таймауты у других пользователей.'}

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

Частые вопросы

Можно ли сделать паузу меньше одной секунды?

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

Работает ли пауза в веб-клиенте?

Блокирующие варианты (цикл, COM) в веб-клиенте неприменимы или бессмысленны. Используйте ПодключитьОбработчикОжидания() с интервалом и фоновые задания — это единственный корректный механизм ожидания в браузере.

Как сделать паузу в запросе или в СКД?

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

Почему пауза через COM не срабатывает на сервере?

Чаще всего сервер 1С работает под Linux, где COM-объектов нет в принципе, либо учётной записи службы сервера запрещено создавать COM-объекты. Проверьте журнал регистрации на ошибку создания объекта и замените вызов циклом по дате.

Как прервать паузу досрочно, если пользователь нажал «Отмена»?

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

Итог

Что важно запомнить

Штатного Sleep в 1С нет: короткие задержки делают циклом по ТекущаяДата(), на Windows-клиенте — через COM WScript.Shell, а длительные ожидания и веб-клиент требуют фоновых заданий и обработчика ожидания. Никогда не ставьте паузу внутри транзакции и не заменяйте ею ожидание конкретного результата.