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

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

Как создать задержку в 1С

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

Во встроенном языке 1С нет штатной функции Sleep или «Задержка», поэтому разработчики реализуют паузу обходными путями. Чаще всего задержка нужна при обмене с внешними сервисами (ожидание ответа API), при повторных попытках подключения, при опросе состояния фонового задания или при работе с оборудованием, которому требуется время на обработку команды.

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

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

Почему в 1С нет штатной функции задержки

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

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

Способ 1. Задержка через COM-объект WScript.Shell

Наиболее популярный способ в среде Windows — использовать COM-объект WScript.Shell и его метод Sleep, точнее — объект WScript через создание экземпляра. В 1С это выглядит так:

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

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

Команда timeout /t 5 приостанавливает выполнение на 5 секунд. Параметр Истина в методе Run означает ожидание завершения команды, то есть код 1С продолжится только после окончания паузы. Альтернатива — классический трюк с ping:

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

Шелл.Run("ping 127.0.0.1 -n 6", 0, Истина); // примерно 5 секунд

Ping отправляет запросы с интервалом около секунды, поэтому для паузы в N секунд указывают N+1 пакет. Способ работает и на старых версиях Windows, где команда timeout может отсутствовать.

Способ 2. Задержка на сервере Linux

На сервере 1С под Linux COM-объекты недоступны, но можно запустить системную команду через ЗапуститьПриложение с ожиданием завершения:

Команда = "sleep 5";

ЗапуститьПриложение(Команда, , Истина);

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

Кроссплатформенный вариант — определить тип системы и выбрать команду автоматически:

СистемнаяИнформация = Новый СистемнаяИнформация;

Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86

Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда

Команда = "ping 127.0.0.1 -n 6";

Иначе

Команда = "sleep 5";

КонецЕсли;

ЗапуститьПриложение(Команда, , Истина);

Способ 3. Пауза через HTTP-запрос с таймаутом

Если запуск внешних приложений запрещён, используют хитрость с HTTPСоединение: устанавливают соединение к заведомо «молчащему» адресу с заданным таймаутом. Соединение само ждёт указанное время, после чего отваливается по таймауту — фактически это и есть задержка.

Попытка

Соединение = Новый HTTPСоединение("127.0.0.1", 1, , , , 5); // таймаут 5 секунд

Соединение.Получить(Новый HTTPЗапрос("/"));

Исключение

// таймаут — задержка выполнена

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

Этот приём работает на любой платформе без внешних команд, но создаёт сетевую активность и исключение, что не всегда приемлемо. Используйте его как запасной вариант, когда другие способы недоступны.

Способ 4. Ожидание результата через фоновые задания

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

// На клиенте

Процедура НачатьОжидание()

ПодключитьОбработчикОжидания("ПроверитьГотовность", 5, Ложь);

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

Процедура ПроверитьГотовность()

Если ЗаданиеЗавершеноНаСервере() Тогда

ОтключитьОбработчикОжидания("ПроверитьГотовность");

// обработать результат

КонецЕсли;

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

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

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

WScript.Shell + ping/timeout

Просто и надёжно, но только Windows и только вне безопасного режима

ЗапуститьПриложение + sleep

Работает на Linux-сервере, требует права запуска внешних приложений

HTTP-таймаут

Кроссплатформенно без внешних команд, но неточно и создаёт исключение

Обработчик ожидания + фоновое задание

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

Точная задержка в цикле и почему это плохая идея

Иногда встречается «задержка» через пустой цикл с проверкой времени:

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

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

КонецЦикла;

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

Типичные ошибки
01
Пустой цикл ожидания — загружает процессор на 100% и блокирует сеанс без пользы
02
Задержка в клиентском коде формы — интерфейс зависает, пользователь не может работать
03
Игнорирование безопасного режима — COM и запуск приложений на сервере выдают ошибку, пауза не выполняется
04
Задержка внутри транзакции — увеличивает время блокировок и риск взаимоблокировок
05
Ожидание фиксированное время вместо проверки результата — код ждёт дольше, чем нужно, или не дожидается готовности

Где размещать задержку и как проверить результат

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

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

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

// ... вызов задержки ...

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

Сообщить("Пауза: " + Длительность + " мс");

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

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

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

Близка к заданной, отклонение в пределах секунды

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

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

Поведение интерфейса
Норма

Форма остаётся отзывчивой (обработчик ожидания)

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

Форма зависает на время паузы

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

Нет ошибок о запрете COM или запуска приложений

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

Ошибки безопасного режима или отказа в доступе

Загрузка процессора
Норма

Во время паузы нагрузка минимальна

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

Ядро загружено на 100% — признак пустого цикла

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

Есть ли в 1С аналог Sleep из других языков?

Нет, штатной функции задержки во встроенном языке нет. Используются обходные способы: COM-объект WScript.Shell с командой timeout или ping, запуск системной команды sleep на Linux, HTTP-запрос с таймаутом либо обработчик ожидания на клиенте.

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

Подключите обработчик ожидания командой ПодключитьОбработчикОжидания с нужным интервалом. Код продолжит выполняться по таймеру, а интерфейс останется отзывчивым. Это единственный корректный способ «подождать» в клиентском коде.

Почему COM-объект WScript.Shell выдаёт ошибку на сервере?

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

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

Точно — нет. Команды ping и timeout оперируют секундами, ТекущаяДата имеет секундную точность. Метод Sleep объекта WScript формально принимает миллисекунды, но фактическая точность в 1С ограничена. Для субсекундных пауз платформа 1С не предназначена.

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

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

Что лучше: ждать фиксированное время или проверять результат?

Проверять результат почти всегда лучше: код не ждёт лишнего и не продолжает работу раньше готовности. Фиксированная пауза оправдана только когда событие нельзя проверить программно, например при ограничении частоты запросов к внешнему API.

Итог

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

Штатной функции задержки в 1С нет. На Windows используют WScript.Shell с timeout или ping, на Linux — команду sleep через ЗапуститьПриложение, универсальный запасной вариант — HTTP-таймаут. На клиенте вместо блокирующей паузы применяйте обработчик ожидания, длительные ожидания выносите в фоновые задания и никогда не ставьте задержку внутри транзакции.