Как сделать паузу при выполнении кода 1С на сервере Linux

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Метод 1: Использование встроенной функции ВызватьПаузу (Платформа 8.3.25+)

Начиная с версии 8.3.25, разработчики 1С добавили долгожданный штатный механизм для реализации задержки. Рассмотрим подробнее синтаксис и особенности этого метода.

Для вызова паузы используется метод ВызватьПаузу(). Он принимает один параметр — интервал в миллисекундах.


// Приостановить выполнение на 5 секунд (5000 миллисекунд)
ВызватьПаузу(5000);

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

  1. Контекст вызова: Метод недоступен в обычном клиент-серверном вызове. Если вы вызовете серверную процедуру с клиента, и в ней сработает ВызватьПаузу, система сгенерирует исключение. Данный метод предназначен для фоновых заданий, HTTP-сервисов и Web-сервисов.
  2. Транзакции: Вызов паузы запрещен внутри открытой транзакции. Если ваш код находится между НачатьТранзакцию() и ЗафиксироватьТранзакцию(), использование метода приведет к ошибке.
  3. Эффективность: Это самый «чистый» способ с точки зрения ресурсов, так как поток переходит в состояние ожидания системного события и практически не потребляет процессорное время.

Метод 2: Использование Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация построена на базе БСП, вы можете воспользоваться готовым методом из программного интерфейса библиотеки. Это наиболее универсальный способ для версий платформы ниже 8.3.25.

Разберем пример вызова:


// Использование метода паузы из общего модуля БСП
ОбщегоНазначения.Пауза(10); // Параметр в секундах

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

Метод 3: Ожидание через фоновые задания (Кроссплатформенный способ)

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

Рассмотрим пример реализации функции:


Процедура ВыполнитьСервернуюПаузу(Секунд)
    Параметры = Новый Массив;
    // Запускаем пустую процедуру как фоновое задание
    Задание = ФоновыеЗадания.Выполнить("ОбщегоНазначения.ПустаяПроцедура", Параметры);
    Попытка
        // Метод ОжидатьЗавершения приостанавливает текущий поток
        Задание.ОжидатьЗавершения(Секунд);
    Исключение
        // Исключение возникнет по истечении таймаута, что нам и нужно
    КонецПопытки;
КонецПроцедуры

Этот способ отлично работает на Linux и Windows. Основное преимущество — поток 1С действительно «спит», не нагружая ядро процессора бесконечным вычислением текущей даты.

Метод 4: Системные команды Linux (утилита sleep)

Поскольку наш сервер работает на ОС Linux, мы можем делегировать задачу управления временем самой операционной системе. Для этого воспользуемся командой sleep.

Выясним, как это реализовать в коде:


// Команда для Linux, которая приостановит выполнение на 10 секунд
КомандаСистемы = "sleep 10";
ЗапуститьПриложение(КомандаСистемы, , Истина); 

Важные моменты:

Метод 5: Хакерский способ через HTTP-запрос

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


Процедура ПаузаЧерезHTTP(Секунд)
    // Пытаемся подключиться к заведомо неверному адресу
    Соединение = Новый HTTPСоединение("127.0.0.2", 80, , , , Секунд);
    Попытка
        Соединение.Получить(Новый HTTPЗапрос("/"));
    Исключение
        // Мы просто дождались таймаута
    КонецПопытки;
КонецПроцедуры

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

Почему нельзя использовать цикл с ТекущаяДата()?

Разберем типичную ошибку начинающих разработчиков. Часто можно встретить такой код:


// ПЛОХОЙ ПРИМЕР: Нагружает процессор на 100%
КонечнаяДата = ТекущаяДата() + 10;
Пока ТекущаяДата() < КонечнаяДата Цикл
    // Пустой цикл
КонецЦикла;

Никогда не используйте этот метод на сервере! В этом состоянии процесс 1С начинает непрерывно опрашивать системное время, полностью захватывая одно ядро процессора. Если сервер Linux обслуживает много пользователей, такая «пауза» одного сотрудника может привести к замедлению работы всей системы для остальных. Все перечисленные выше методы (особенно ВызватьПаузу и ФоновыеЗадания) лишены этого недостатка.

Резюме и рекомендации

Проанализировав все способы, мы можем сделать следующие выводы:

  1. Если у вас платформа 8.3.25 и выше, и вы находитесь в контексте фонового задания — используйте ВызватьПаузу().
  2. Если используется конфигурация на базе БСП — используйте ОбщегоНазначения.Пауза().
  3. Для универсальных серверных решений на старых платформах оптимальным будет метод с фоновым заданием и ОжидатьЗавершения().
  4. Для специфических задач на Linux можно использовать ЗапуститьПриложение("sleep ...").

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

← На главную