Разработка и Конфигурация · 11 мин
Как сделать задержку в 1С: рабочие способы и примеры
Способы сделать задержку в 1С: пауза в коде, обработчики ожидания, фоновые задания и асинхронные вызовы. Примеры кода, ограничения и типичные ошибки.
Во встроенном языке 1С нет прямого аналога функции Sleep, поэтому задача «сделать задержку» решается несколькими разными приёмами в зависимости от контекста. Пауза внутри серверного кода, отложенный вызов процедуры на клиенте и периодический запуск обработчика — это разные механизмы с разными ограничениями, и выбирать их нужно осознанно.
Главное ограничение, о котором часто забывают: блокирующая пауза «замораживает» выполнение кода. Если такую задержку поместить в клиентский модуль формы, интерфейс перестанет отвечать, а пользователь увидит «зависшую» программу. Поэтому в управляемых формах вместо «сна» применяют механизм ожидания, который не блокирует интерфейс.
Ниже разобраны основные способы: блокирующая задержка на сервере через внешние средства, обработчики ожидания в управляемых формах, фоновые задания для длительных операций и асинхронные вызовы веб-сервисов. Для каждого приведены примеры кода, условия применимости и способы проверить, что задержка работает как задумано.
Какие задачи решает задержка и какой способ выбрать
Прежде чем писать код, определите, зачем нужна пауза. Типичные сценарии: повторный запрос к внешнему API после ошибки, ожидание готовности файла или ответа оборудования, периодический опрос состояния фонового задания, отложенное обновление данных в форме после действия пользователя. Для каждого сценария есть подходящий инструмент, и подмена одного другим приводит к зависаниям или лишней нагрузке.
Ключевой критерий выбора — где выполняется код и можно ли блокировать поток. На клиенте блокировка недопустима почти всегда: пользователь должен продолжать работать. На сервере короткая блокирующая пауза допустима, но она занимает рабочий процесс кластера, поэтому длительные ожидания лучше оформлять через фоновые задания или регламентные механизмы.
Как выбрать способ задержки
Обработчик ожидания — основной способ на клиенте
В управляемых формах задержку реализуют методом ПодключитьОбработчикОжидания. Он указывает платформе вызвать заданную процедуру через заданный интервал в секундах, не блокируя интерфейс. Это правильная замена «сна» на клиенте: пользователь продолжает работать, а платформа сама вызовет вашу процедуру, когда время выйдет.
Метод принимает имя процедуры, интервал в секундах и признак однократного вызова. Если третий параметр равен Истина, процедура выполнится один раз; иначе она будет вызываться периодически до отключения. Процедура-обработчик должна быть объявлена с директивой &НаКлиенте и без параметров.
&НаКлиенте
Процедура КомандаСЗадержкой(Команда)
// Отложенный вызов через 5 секунд, однократно
ПодключитьОбработчикОжидания("ОтложенноеДействие", 5, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ОтложенноеДействие()
ПоказатьОповещениеПользователя("Прошло 5 секунд");
КонецПроцедуры
Для отмены ожидания используется ОтключитьОбработчикОжидания("ИмяПроцедуры"). Обязательно отключайте периодические обработчики при закрытии формы или когда они больше не нужны — «забытый» обработчик продолжает срабатывать и может обращаться к уже недействительным данным формы.
Учтите точность таймера: интервал меньше одной секунды задать можно (дробным числом), но реальная точность ограничена механизмами платформы и загрузкой клиента. Для задач, требующих точности до миллисекунд, обработчик ожидания не подходит.
- 1Создайте процедуру &НаКлиенте без параметров с нужной логикой
- 2В месте запуска вызовите ПодключитьОбработчикОжидания с именем процедуры и интервалом
- 3Укажите Истина для однократного вызова или Ложь для периодического
- 4При необходимости добавьте ОтключитьОбработчикОжидания в обработчик ПередЗакрытием
- 5Проверьте работу: действие должно выполниться через заданное время без зависания формы
Блокирующая пауза на сервере
Иногда пауза нужна именно в серверном коде — например, между повторными попытками обращения к веб-сервису. Классический приём в файловом и клиент-серверном варианте на Windows — использование COM-объекта WScript.Shell с вызовом утилиты, которая «молчит» заданное время, чаще всего ping с таймаутом.
&НаСервере
Процедура Пауза(Секунды)
Shell = Новый COMОбъект("WScript.Shell");
// ping с интервалом: n+1 пакетов дают примерно n секунд ожидания
Shell.Run("ping -n " + Формат(Секунды + 1, "ЧГ=") + " 127.0.0.1", 0, Истина);
КонецПроцедуры
Этот способ работает только там, где доступен COM: на Windows-сервере и в толстом клиенте. На Linux-сервере, в веб-клиенте и при запрете COM-объектов в настройках безопасности кластера он не сработает. Альтернатива — подключение внешней компоненты с функцией Sleep, но это требует установки и сопровождения компоненты.
Важно понимать цену блокирующей паузы: пока код «спит», рабочий процесс сервера занят. Пауза в 1–3 секунды между попытками обращения к API — приемлема. Пауза в несколько минут внутри транзакции или вызова с клиента — плохое решение: она держит соединения, блокировки и ресурсы кластера.
Фоновые задания для длительных операций
Если логика требует «подождать и продолжить», а ожидание длится десятки секунд и дольше, правильная архитектура — фоновое задание. Метод ФоновыеЗадания.Выполнить запускает процедуру в отдельном сеансе, а клиентская форма периодически проверяет его состояние обработчиком ожидания. Так пользователь не ждёт у «замерзшего» окна, а сервер не держит лишнее соединение.
&НаСервере
Функция ЗапуститьОбмен()
ПараметрыЗадания = Новый Массив;
Задание = ФоновыеЗадания.Выполнить("ОбменДанными.ВыполнитьОбмен",
ПараметрыЗадания, , "Обмен с сайтом");
Возврат Задание.УникальныйИдентификатор;
КонецФункции
&НаКлиенте
Процедура ПроверитьЗавершение()
Если ЗаданиеЗавершено(ИдентификаторЗадания) Тогда
ОтключитьОбработчикОжидания("ПроверитьЗавершение");
ПоказатьОповещениеПользователя("Обмен завершён");
КонецЕсли;
КонецПроцедуры
Внутри самого фонового задания паузы между итерациями (например, при ожидании ответа внешней системы) допустимы тем же COM-приёмом, поскольку задание выполняется в своём сеансе и никому не мешает. Но и здесь задавайте разумный предел ожидания и счётчик попыток, иначе задание может «висеть» бесконечно.
Для периодических задач — обменов, загрузок курсов, очистки данных — паузы в коде вообще не нужны: используйте регламентные задания с расписанием. Это штатный механизм платформы, который проще сопровождать и мониторить.
Ожидание в асинхронных сценариях и расширениях
В тонком и веб-клиенте многие операции изначально асинхронны: диалоги, работа с файлами, вызовы через НачатьВызовHTTP и подобные методы. Здесь «задержка» встроена в саму модель: вы запускаете операцию и получаете управление в обработчике оповещения, когда она завершится. Пытаться вставить синхронную паузу в такую цепочку — ошибка проектирования.
Для ожидания внешнего события (например, появления файла от оборудования) применяют цикл опроса с обработчиком ожидания: раз в несколько секунд клиент вызывает серверную функцию проверки, и при успехе цикл останавливается. Обязательно задайте максимальное время ожидания, чтобы при сбое оборудования форма не опрашивала сервер бесконечно.
Типичные ошибки и как их проверить
Самая частая ошибка — «задержка» пустым циклом вида Пока ТекущаяДата() < Конец Цикл КонецЦикла. Такой код загружает ядро процессора на полную мощность, блокирует поток и на клиенте делает интерфейс неотзывчивым. Второй по частоте промах — обработчик ожидания с именем процедуры, написанным с опечаткой: платформа молча не вызовет процедуру, и задержка «не сработает» без сообщения об ошибке.
Ещё одна группа проблем — забытые периодические обработчики. Если процедура с интервалом не отключается, она продолжает выполняться, обращаться к серверу и нагружать систему, даже когда её результат уже не нужен. Проверяйте логику отключения при закрытии формы и при получении нужного результата.
Проверить работу задержки несложно: зафиксируйте время до и после вызова через ТекущаяДата() или ТекущаяУниверсальнаяДатаВМиллисекундах() и выведите разницу в журнал регистрации или сообщение. Для обработчиков ожидания убедитесь, что процедура реально вызывается — поставьте в её начало отладочное сообщение или точку останова.
Как проверить результат
Форма реагирует на действия пользователя
Окно не отвечает — используется блокирующая пауза
Процедура срабатывает через заданный интервал
Процедура не вызывается — проверьте имя и режим формы
Во время ожидания загрузка не растёт
Ядро загружено на 100% — в коде пустой цикл
После результата обработчик отключён
Вызовы продолжаются — нет ОтключитьОбработчикОжидания
FAQ
Есть ли в 1С встроенная функция Sleep?
Нет, во встроенном языке прямой функции ожидания нет. На клиенте её заменяет механизм обработчиков ожидания, на сервере — пауза через внешние средства (COM-объект, компонента) либо перенос логики в фоновое задание.
Как сделать паузу меньше секунды?
Обработчик ожидания принимает дробный интервал, но реальная точность ограничена таймером платформы и загрузкой клиента. Для задач с точностью до миллисекунд штатных средств нет — обычно это признак того, что задачу нужно решать иначе, например асинхронным вызовом.
Почему ПодключитьОбработчикОжидания не срабатывает?
Чаще всего причины: опечатка в имени процедуры, процедура объявлена с параметрами или без директивы &НаКлиенте, форма закрыта до срабатывания. Проверьте имя строкой в точности как в объявлении и добавьте отладочное сообщение в начало процедуры.
Можно ли использовать паузу в обычном приложении?
В обычных формах обработчик ожидания тоже доступен, а на толстом клиенте под Windows работает и COM-пауза через WScript.Shell. Однако блокирующая пауза в обычной форме так же зависает интерфейс, поэтому предпочтителен механизм ожидания.
Как ждать ответа внешнего сервиса, не блокируя сеанс?
Запустите обмен фоновым заданием, а в форме подключите периодический обработчик ожидания, который проверяет состояние задания. Задайте максимальное время ожидания и отключайте обработчик при получении результата или таймауте.
Опасна ли пауза внутри транзакции?
Да. Пока транзакция открыта, удерживаются блокировки данных, и пауза увеличивает вероятность конфликтов и взаимоблокировок. Если ожидание необходимо, выполняйте его до начала транзакции или после фиксации.
Что важно запомнить
Готового Sleep в 1С нет: на клиенте используйте ПодключитьОбработчикОжидания, на сервере — короткую паузу через COM или компоненту, длительные операции выносите в фоновые задания. Никогда не делайте задержку пустым циклом и не ставьте долгие паузы внутри транзакций. Всегда отключайте периодические обработчики и задавайте предел ожидания.