Разработка и Конфигурация · 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, но грузит процессор и блокирует сеанс. Подходит для пауз до нескольких секунд.
Поток реально спит, процессор не нагружается, но только Windows и только там, где разрешены COM-объекты. Не работает в веб-клиенте.
Единственный правильный вариант для длительных ожиданий и веб-клиента. Требует перестройки логики на асинхронную.
Как выбрать способ под свою задачу
Выбор определяется тремя факторами: где выполняется код (клиент, сервер, веб-клиент), как долго нужно ждать и что именно вы ждёте — просто время или результат операции.
Как выбрать действие
Отдельный случай — паузы в обменах с внешними API, когда сервис просит не чаще определённого интервала. Здесь надёжнее не «спать» в цикле, а хранить время последнего обращения и перед каждым запросом проверять, прошло ли достаточно времени. Такой подход не блокирует сеанс и корректно работает при любом количестве пользователей.
Проверка результата и типичные ошибки
После внедрения паузы проверьте три вещи: фактическую длительность задержки, поведение интерфейса во время ожидания и отсутствие исключений в журнале регистрации. Для замера длительности удобно зафиксировать время до и после паузы и вывести разницу в сообщение.
Как проверить результат
Отклонение от заданной — доли секунды для цикла, до секунды для COM-вызова
Пауза заметно длиннее заданной или не выполняется вовсе
Для короткой паузы — кратковременное «подвисание», для длительной — индикатор и рабочий интерфейс
Форма «замерзает» на десятки секунд без обратной связи
Нет ошибок создания COM-объектов и таймаутов
Ошибки «Ошибка создания объекта» или «Превышен таймаут»
Самая опасная ошибка из перечисленных — пауза внутри транзакции. Пока транзакция открыта, захваченные ею записи заблокированы для других сеансов. Даже пятисекундная задержка в таком месте при интенсивной работе пользователей способна вызвать цепочку таймаутов. Правило простое: сначала завершите транзакцию, потом ждите.
Частые вопросы
Можно ли сделать паузу меньше одной секунды?
Да, через цикл с ТекущаяУниверсальнаяДатаВМиллисекундах(). Учтите, что реальная точность зависит от таймера операционной системы и обычно составляет десятки миллисекунд, поэтому на задержки в 1–5 мс рассчитывать не стоит.
Работает ли пауза в веб-клиенте?
Блокирующие варианты (цикл, COM) в веб-клиенте неприменимы или бессмысленны. Используйте ПодключитьОбработчикОжидания() с интервалом и фоновые задания — это единственный корректный механизм ожидания в браузере.
Как сделать паузу в запросе или в СКД?
Никак: язык запросов и схема компоновки данных не поддерживают задержек, и вставлять их туда не нужно. Если требуется выдержать интервал между обращениями к внешнему сервису, логику паузы размещают в коде, который формирует или обрабатывает данные, а не в самом запросе.
Почему пауза через COM не срабатывает на сервере?
Чаще всего сервер 1С работает под Linux, где COM-объектов нет в принципе, либо учётной записи службы сервера запрещено создавать COM-объекты. Проверьте журнал регистрации на ошибку создания объекта и замените вызов циклом по дате.
Как прервать паузу досрочно, если пользователь нажал «Отмена»?
Блокирующую паузу прервать нельзя — это ещё один аргумент против неё. В асинхронной схеме с обработчиком ожидания отмена реализуется просто: обработчик проверяет флаг отмены и прекращает дальнейшие проверки, а фоновое задание отменяется методом Отменить().
Что важно запомнить
Штатного Sleep в 1С нет: короткие задержки делают циклом по ТекущаяДата(), на Windows-клиенте — через COM WScript.Shell, а длительные ожидания и веб-клиент требуют фоновых заданий и обработчика ожидания. Никогда не ставьте паузу внутри транзакции и не заменяйте ею ожидание конкретного результата.