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

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

1С: как поставить задержку (паузу) в коде

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

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

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

Все примеры применимы к платформе 1С:Предприятие 8.3. Перед внедрением любого варианта в рабочую базу протестируйте его на копии, особенно если пауза используется внутри транзакций или регламентных заданий.

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

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

Из этого следует главный принцип: если задачу можно переформулировать как «выполнить действие через N секунд» или «повторять проверку каждые N секунд», это предпочтительнее, чем блокирующая пауза. Блокирующая задержка оправдана только там, где продолжение выполнения в принципе невозможно без ожидания — например, при последовательном обмене с оборудованием внутри одной процедуры.

Задержка на клиенте через цикл с обработкой ожидания

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

// Пауза 5 секунд на клиенте

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

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

// короткие итерации, интерфейс не блокируется надолго

КонецЦикла;

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

Обратите внимание: функция ТекущаяДата() на клиенте возвращает время клиентского компьютера. Если код может выполняться и на сервере, используйте универсальные проверки, а для серверной логики — ТекущаяДатаСеанса(), чтобы избежать расхождений часовых поясов.

Неблокирующая задержка через ПодключитьОбработчикОжидания

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

// Однократный вызов процедуры через 10 секунд

ПодключитьОбработчикОжидания("ВыполнитьПослеПаузы", 10, Истина);

// Процедура должна быть объявлена в модуле формы:

&НаКлиенте

Процедура ВыполнитьПослеПаузы()

// код, выполняемый после паузы

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

Третий параметр (Истина) означает однократный вызов; без него обработчик будет срабатывать периодически, пока его не отключат методом ОтключитьОбработчикОжидания. Минимальный практический интервал ограничен — слишком маленькие значения (доли секунды) создают лишнюю нагрузку и не гарантируют точности.

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

Как организовать паузу без зависания формы
  1. 1
    Определите, где исполняется код: клиент, сервер или фоновое задание
  2. 2
    Для клиента вынесите продолжение логики в отдельную процедуру
  3. 3
    Вызовите ПодключитьОбработчикОжидания с интервалом и флагом однократности
  4. 4
    Убедитесь, что процедура объявлена с директивой &НаКлиенте и доступна по имени
  5. 5
    Проверьте, что форма остаётся отзывчивой, а действие срабатывает через заданное время

Пауза на сервере и в фоновых заданиях

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

// Серверная пауза 3 секунды

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

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

КонецЦикла;

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

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

Задержка через COM-объект и другие внешние средства

На компьютерах с Windows, где доступен COM, паузу можно реализовать через объект WScript.Shell или динамическую библиотеку. Способ работает только там, где разрешены COM-объекты: обычно это толстый клиент или сервер под Windows с соответствующими правами.

// Пауза через COM (только Windows, где разрешён COM)

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

WshShell.Run("timeout /t 5 /nobreak", 0, Истина);

Недостатки очевидны: зависимость от операционной системы, необходимость прав на создание COM-объектов, непереносимость на Linux-серверы и веб-клиент. В веб-клиенте этот способ не сработает вовсе. Использовать его стоит только как временное решение в закрытой инфраструктуре, где среда исполнения гарантирована.

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

Сравнение способов задержки

Цикл по времени

Прост и переносим, но блокирует поток; подходит для коротких пауз в фоновых заданиях

ПодключитьОбработчикОжидания

Не блокирует интерфейс; работает только на клиенте и требует отдельной процедуры

COM WScript.Shell

Точная системная пауза, но только Windows и только там, где разрешён COM

Фоновое задание + регламентная проверка

Правильный путь для долгих ожиданий; требует перестройки логики на повторные проверки

Правильная альтернатива: ожидание результата вместо сна

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

// Ждём появления файла не дольше 60 секунд

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

ФайлНайден = Ложь;

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

Файл = Новый Файл(ПутьКФайлу);

Если Файл.Существует() Тогда

ФайлНайден = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

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

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

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

Отзывчивость формы при паузе на клиенте
Норма

Окно перерисовывается, кнопки реагируют

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

Форма «зависает» до конца паузы

Нагрузка на сервер
Норма

Рабочие процессы не заняты спящими вызовами

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

Растёт время ожидания в кластере, тайм-ауты вызовов

Логика после паузы
Норма

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

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

Повторные срабатывания или пропуск выполнения

Поведение при неготовности данных
Норма

По истечении тайм-аута фиксируется ошибка

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

Код молча продолжает работу с неполными данными

Типичные ошибки при реализации паузы

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

Также разработчики нередко забывают отключить периодический обработчик ожидания при закрытии формы — в результате процедура продолжает срабатывать и обращается к уже недоступным реквизитам, вызывая ошибки. Ещё одна ловушка — использование ТекущаяДата() в серверном коде вместо ТекущаяДатаСеанса(), что при разнице часовых поясов даёт паузу непредсказуемой длительности.

Типичные ошибки
01
Пауза внутри транзакции — блокировки удерживаются, растут взаимоблокировки
02
Пустой цикл без условия выхода — бесполезная нагрузка на процессор
03
Не отключён обработчик ожидания — ошибки после закрытия формы
04
ТекущаяДата() на сервере вместо ТекущаяДатаСеанса() — неверная длительность паузы
05
COM-способ в веб-клиенте или на Linux — код не выполняется вовсе
06
Фиксированная пауза вместо ожидания условия — потерянное время или гонки данных

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

Начните с вопроса, где исполняется код и что именно вы ждёте. Для однократного отложенного действия в форме выбирайте обработчик ожидания, для короткой паузы в фоновом задании — цикл по времени, для ожидания внешнего результата — цикл с проверкой условия и тайм-аутом. COM-способ оставьте как крайний вариант для закрытых Windows-сред.

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

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

Нужно выполнить действие в форме через несколько секундПодключитьОбработчикОжидания с флагом однократности
Пауза нужна в фоновом задании или на сервереЦикл по ТекущаяДатаСеанса() с обязательным тайм-аутом
Ожидается внешний результат (файл, ответ сервиса)Цикл с проверкой условия и ограничением времени
Долгое ожидание в интерактивном вызовеПеренести логику в фоновое задание, а не ставить паузу
Среда строго Windows и разрешён COMДопустим WScript.Shell как временное решение

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

Итог

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

Штатного Sleep в 1С нет. На клиенте используйте обработчики ожидания, на сервере и в фоновых заданиях — циклы по времени с обязательным тайм-аутом. Никогда не ставьте паузу внутри транзакции и предпочитайте ожидание конкретного условия слепой фиксированной задержке.

Частые вопросы о задержках в 1С

Есть ли в 1С встроенная функция Sleep?

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

Как сделать паузу, чтобы не зависала форма?

Используйте ПодключитьОбработчикОжидания: вынесите продолжение логики в отдельную клиентскую процедуру и вызовите её через нужный интервал. Форма при этом остаётся полностью работоспособной, а действие выполнится по таймеру.

Можно ли поставить задержку в регламентном задании?

Технически можно — циклом по ТекущаяДатаСеанса(). Но длительная пауза занимает рабочий процесс кластера, поэтому вместо сна лучше перенести повторные проверки в расписание задания или в цепочку фоновых заданий.

Почему пауза через цикл грузит процессор?

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

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

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

Как дождаться появления файла, а не просто выждать время?

Организуйте цикл: проверяйте существование файла через объект Файл, прерывайте цикл при успехе и ограничьте общее время ожидания. По истечении тайм-аута зафиксируйте ошибку, чтобы сбой не остался незамеченным.