---
title: Длительная однопоточная операция
slug: примеры-сниппеты-бсп-и-типовые-длительные-операции-и-выполнение-в-фоне/длительная-однопоточная-операция
---
# Схема выполнения длительной серверной операции
Механизм длительных операций БСП необходим для выполнения тяжелых операций без блокирования окна клиентского приложения. По умолчанию платформа блокирует клиентский интерфейс до тех пор, пока серверная операция не будет завершена. Подсистема "Длительные операции" позволяет обойти эту проблему
![diagramma-bez-nazvaniya.drawio.png](https://sinenikolsky.ru/s/QEWSKmHn7HKGJX4/download?path=%2F2025%2F04%2F16&files=fe7a4397-bffe-44ca-be28-f3f909684212.png)

## Создание длительной операции
Длительную операцию необходимо размещать в **экспортной** функции. Рекомендуется выносить их в общий модуль. Например, для примера создаем длительную функцию в общем модуле `МоиДлительныеОперации`
```bsl
Функция МояДлительнаяОперацияНаСервере(ВремяОжидания) Экспорт
	
	// Имитация длительной операции
	КонечнаяДата = ТекущаяДатаСеанса() + ВремяОжидания;
	Пока ТекущаяДатаСеанса() < КонечнаяДата Цикл
		
		//===================================================================================================
		
		// Алгоритмы операции, Очень много страшного тяжелого кода
		
		//===================================================================================================
		
		
		//===================================================================================================
		// Относится к механизму "Длительные операции"
		// Расчет прогресса для сообщения клиенту
		СекундОсталось = КонечнаяДата - ТекущаяДатаСеанса();
		Прогресс = -(Окр((СекундОсталось / ВремяОжидания) * 100, 0)) + 100;
		// Сообщение клиенту
		ДлительныеОперации.СообщитьПрогресс(Прогресс, "Выполняюсь, осталось " + (100 - Прогресс) + "%");	
		//===================================================================================================
		
	КонецЦикла;
	
	// Любой тип, доступный на клиенте.
	// Можно, например, возвращать какой-то сложный табличный документ, или ссылку на какой-нибудь объект.
	Возврат "Все выполнилось хорошо";
	
КонецФункции
```

## Настройка модуля формы

Так как пользователь взаимодействует с формами, очевидно, что инициализация процесса начинается именно с нее. Для примера создадим внешнюю обработку с одним числовым реквизитом и командой. Планируется запускать длительную операцию на то количество секунд, которое введет пользователь
Как показано на схеме, при нажатии на кнопку на стороне клиента должны сформироваться параметры ожидания. 
`Параметры ожидания` — это структура с определенными ключами, на основании которой будут установлены настройки длительной операции. Параметры формируются функцией общего модуля `ДлительныеОперацииКлиент.ПараметрыОжидания`. Описание можно посмотреть в общем модуле. Пример реализации:
```bsl
&НаКлиенте
Процедура ВыполнитьВФоне(Команда)
	
	// Аргументом передается форма, с которой запускается длительное задание
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ТекстСообщения = "Выполняется длительная операция.";
	ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина;
	ПараметрыОжидания.Интервал = 2;
	
	// Структура, которая передается в качестве настроек оповещения при завершении длительной операции
	ПараметрыОповещения = Новый Структура("НавигационнаяСсылка, Пояснение, Картинка, Важное"
											, ""
											, ""
											, Неопределено
											, Ложь);
											
	ПараметрыОповещения.Вставить("Показать", Истина);
	ПараметрыОповещения.Вставить("Текст", "Синхронизация завершена");
	
	ПараметрыОжидания.ОповещениеПользователя = ПараметрыОповещения;
	
	// Инициализация запуска длительной операции. 
	МояДлительнаяОперация = ДлительнаяОперация(УникальныйИдентификатор, "МояДлительнаяОперацияНаСервере", ДлительностьОжидания);
	
	// Определение действия после завершения длительной операции
	ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗавершенияВыполненияДлительнойФункции", ЭтаФорма);
	
	// Запуск ожидания завершения
	ДлительныеОперацииКлиент.ОжидатьЗавершение(МояДлительнаяОперация
												, ОписаниеОповещения
												, ПараметрыОжидания);
	
	
КонецПроцедуры
```
В этом методе есть вызов функции `ДлительнаяОперация`, собственно и запускает выполнение серверной функции. Она возвращает объект, позволяющий отслеживать выполнение операции с клиента в методе `ДлительныеОперацииКлиент.ОжидатьЗавершение`
```bsl
&НаСервереБезКонтекста
Функция ДлительнаяОперация(УИДЭтойФормы, ИмяФункции, ДлительностьОжидания)
	
	// Указываем идентификатор владельца задания, 
	// полный путь до тяжелой операции и дополнительные параметры (до 7 шт),
	// которые необходимо передать в тяжелую операцию
	Операция = ДлительныеОперации.ВыполнитьФункцию(УИДЭтойФормы 
				, "МоиДлительныеОперации." + ИмяФункции
				, ДлительностьОжидания);
	
	Возврат Операция;
	
КонецФункции
```
Также в качестве параметра ожидания на клиенте было передано `ОписаниеОповещения`, которое определяет поведение после завершения выполнения длительной операции. 
> ВАЖНО! Длительная операция может завершиться как удачно, так и нет, и это нужно учитывать
```bsl
&НаКлиенте
Процедура ПослеЗавершенияВыполненияДлительнойФункции(Результат, ДополнительныеПараметры) Экспорт
	
	// В аргумент "Результат" принимается структура с определенными ключами, среди которых 
	// наиболее интересны Статус, АдресРезультата, КраткоеПредставлениеОшибки
	//
	//Если что-то пошло не так, то результат будет Неопределено
	Если Результат = Неопределено Тогда
		Сообщить("Ошибка выполнения");
		Возврат;
	КонецЕсли;
	
	// Если результат не равер Неопределено, то анализируется статус
	// Варианты статусов - "Выполняется", "Выполнено", "Ошибка", "Отменено"
	Если Результат.Статус = "Выполнено" Тогда
		// Возвращаемое значение длительной операции помещается во временное хранилище
		// и передается на клиент в качестве адреса
		Сообщение = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
	ИначеЕсли Результат.Статус = "Ошибка" Тогда
		Сообщение = "Ошибка выполнения: " 
		+ Символы.ПС
		+ Результат.КраткоеПредставлениеОшибки;
	Иначе
		Сообщение = "Неопределенный результат выполнения длительной операции. См. журнал регистрации";				
	КонецЕсли;
	
	Сообщить(Сообщение);			
	
```