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

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

Как сделать паузу в коде 1С

Как сделать паузу в коде 1С: метод Sleep через WScript.Shell, ожидание через HTTP-запрос, обработчики ожидания и фоновые задания. Примеры кода и ограничения.

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

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

Почему в 1С нет встроенной функции паузы и что это меняет

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

Практический вывод: прежде чем делать задержку, стоит проверить, не является ли задача на самом деле ожиданием события. Если нужно «подождать, пока документ проведётся в другом сеансе» или «дождаться ответа веб-сервиса», почти всегда лучше подходит обработчик ожидания или фоновое задание, а не «заморозка» кода. Пауза как таковая оправдана в основном для коротких интервалов между повторными попытками (retry) и при работе с внешними API, ограничивающими частоту запросов.

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

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

Нужна пауза до 60 секунд на толстом клиентеИспользуйте WScript.Shell.Sleep — просто и надёжно
Пауза нужна в серверном коде или веб-клиентеИспользуйте холостой HTTP-запрос с таймаутом
Нужно периодически повторять действие без блокировки интерфейсаПодключите обработчик ожидания
Ожидание длится минуты и дольшеИспользуйте фоновое задание или регламентное задание с повторным запуском

Пауза на клиенте через WScript.Shell.Sleep

Самый известный приём — вызов метода Sleep объекта Windows Script Host через COM. Он работает на толстом и тонком клиенте под Windows, где разрешено создание COM-объектов. Код простой: создаётся объект WScript.Shell, и вызывается метод Sleep с длительностью в миллисекундах.

Процедура Пауза(Секунды)

Попытка

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

Оболочка.Run("timeout /t " + Формат(Секунды, "ЧГ=") + " /nobreak", 0, Истина);

Исключение

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

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

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

Обратите внимание: сам объект WScript.Shell не имеет метода Sleep — «сон» обеспечивается запуском консольной команды timeout с ожиданием завершения (третий параметр Истина). Альтернативный вариант — создать COM-объект «WScript.Shell» и использовать его метод Popup с таймаутом, либо напрямую обратиться к «MSScriptControl.ScriptControl». Все эти приёмы объединяет одно ограничение: они недоступны в веб-клиенте и на Linux-сервере.

Пауза на сервере через холостой HTTP-запрос

На сервере COM-объекты Windows недоступны (а на Linux их нет в принципе), поэтому используется другой трюк: HTTP-запрос к заведомо несуществующему адресу с заданным таймаутом. Соединение не устанавливается, и метод Get «молчит» ровно столько, сколько указано в свойстве Таймаут. Это универсальный способ, работающий и на сервере, и на клиенте, и под Linux.

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

Если Секунды <= 0 Тогда

Возврат;

КонецЕсли;

Попытка

Соединение = Новый HTTPСоединение("127.0.0.1", 1, , , , Секунды);

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

Исключение

// ожидаемая ошибка соединения — это и есть пауза

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

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

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

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

Обработчик ожидания: пауза без блокировки интерфейса

Когда цель — не «заморозить» выполнение, а выполнить действие через заданный интервал или повторять его периодически, правильный инструмент — обработчик ожидания. Метод ПодключитьОбработчикОжидания указывает имя процедуры формы и интервал в секундах (минимум 0,1 с, для однократного вызова есть флаг «однократно»).

&НаКлиенте

Процедура КомандаСОжиданием(Команда)

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

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

&НаКлиенте

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

// код, который выполнится через 5 секунд

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

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

Фоновые задания и ожидание их завершения

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

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

Задание = Задание.ОжидатьЗавершенияВыполнения(60); // ждём не более минуты

Если Задание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда

Результат = ПолучитьИзВременногоХранилища(АдресРезультата);

КонецЕсли;

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

Частая схема retry-цикла: попытка обращения к API → при ошибке пауза 1–2 секунды через холостой HTTP-запрос → повтор, не более 3–5 попыток с нарастающим интервалом. Это защищает и вашу базу от лишней нагрузки, и внешний сервис от блокировки вашего IP за частые запросы.
ПЗ
Практическое замечание

Пауза в запросах к внешним сервисам и ограничения частоты

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

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

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

Типичные ошибки
01
Пауза внутри транзакции — удерживаются блокировки, другие пользователи получают ошибки ожидания; выносите задержку за пределы транзакции
02
Пустой цикл ожидания по текущей дате — загружает ядро процессора на 100%; заменяйте холостым HTTP-запросом или обработчиком ожидания
03
WScript.Shell в веб-клиенте или на Linux — код падает с ошибкой создания COM-объекта; проверяйте среду выполнения
04
Обработчик ожидания без отключения — процедура вызывается бесконечно и грузит сеанс; всегда отключайте обработчик при достижении результата
05
Многоминутная пауза в интерактивной форме — интерфейс зависает, пользователь принудительно завершает сеанс; для длительных ожиданий используйте фоновые задания

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

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

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

Поведение интерфейса во время задержки
Норма

Форма отвечает, если использован обработчик ожидания; зависание допустимо только на пару секунд при Sleep

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

Окно «не отвечает» дольше нескольких секунд

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

Нагрузки нет — ожидание через HTTP-таймаут или обработчик

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

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

Блокировки в кластере во время паузы
Норма

Другие сеансы работают без ошибок ожидания

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

Растут конфликты блокировок — пауза внутри транзакции

Повторные вызовы обработчика
Норма

Обработчик отключается после достижения цели

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

Процедура продолжает срабатывать после завершения задачи

Частые вопросы о паузах в 1С

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

Нет, во встроенном языке такой функции не существует по архитектурным причинам. Вместо неё применяют описанные приёмы: команду timeout через WScript.Shell на клиенте, холостой HTTP-запрос с таймаутом на сервере, обработчики ожидания и фоновые задания для асинхронных сценариев.

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

Универсальный вариант — холостой HTTP-запрос к несуществующему адресу (например, 127.0.0.1 на свободный порт) с таймаутом соединения, равным нужной задержке. Он не зависит от операционной системы и режима работы, но требует, чтобы вызов не выполнялся внутри транзакции.

Как повторять действие каждые 10 секунд без зависания формы?

Подключите обработчик ожидания с интервалом 10 и без флага однократности: ПодключитьОбработчикОжидания("МойОбработчик", 10). Внутри обработчика проверяйте условие завершения и вызывайте ОтключитьОбработчикОжидания, когда повторения больше не нужны.

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

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

Почему пауза через пустой цикл — плохая идея?

Цикл вида «Пока ТекущаяДата < ВремяОкончания Цикл» непрерывно выполняет вычисления и полностью загружает одно ядро процессора на всё время ожидания. На сервере это мешает другим сеансам. Замените такой цикл HTTP-таймаутом или обработчиком ожидания — они не расходуют процессорное время.

Как дождаться завершения фонового задания с таймаутом?

Вызовите у объекта задания метод ОжидатьЗавершенияВыполнения с параметром — числом секунд ожидания. Метод вернёт управление либо при завершении задания, либо по истечении таймаута; дальше проверьте свойство Состояние, чтобы понять, завершилось ли задание успешно.

Итог

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

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