Подключение к фоновым заданиям 1С

Случаются ситуации, что фоновое задание запущенное пользователем, продолжает работать и после выхода самого пользователя из 1С. Как же исключить повторный запуск фонового задания пользователем? Ну и заодно показать текущий прогресс выполнения задания. На самом деле всё оказалось просто. В 1С есть функционал получения полного списка выполняемых в текущий момент фоновых заданий:

ФоновыеЗадания.ПолучитьФоновыеЗадания();		

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

&НаКлиенте
Процедура ВыгрузкаКвитанцийНаБумаге(Команда)
	этаформа.ИндикаторВыгрузкаКвитанций=0;
	ЗапуститьФЗВыгрузкиКвитанций();					
	ПодключитьОбработчикОжидания("ИндикаторВыполненияВыгрузкиКвитанцийИсточник1",1,ложь);
	ПодключитьОбработчикОжидания("ИндикаторВыполненияВыгрузкиКвитанцийИсточник2",1,ложь);
КонецПроцедуры       

&НаСервере
Процедура ЗапуститьФЗВыгрузкиКвитанций()		
	Фоновые = ФоновыеЗадания.ПолучитьФоновыеЗадания();		
	Для Каждого Фоновое из Фоновые Цикл
		если Фоновое.ИмяМетода="СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник1" тогда
			если Фоновое.Состояние<>СостояниеФоновогоЗадания.ЗавершеноАварийно и Фоновое.Состояние<>СостояниеФоновогоЗадания.Завершено тогда
				сообщить("-предыдущее задание еще не завершено!");
				объект.ФЗ_ВыгрузкаКвитанций = Фоновое.УникальныйИдентификатор;									
				возврат;
			конецесли;
		конецесли;				
		если Фоновое.ИмяМетода="СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник2" тогда
			сообщить("-предыдущее задание еще не завершено!");
			если Фоновое.Состояние<>СостояниеФоновогоЗадания.ЗавершеноАварийно и Фоновое.Состояние<>СостояниеФоновогоЗадания.Завершено тогда
				сообщить("-предыдущее задание еще не завершено!");
				объект.ФЗ_ВыгрузкаКвитанций2 = Фоновое.УникальныйИдентификатор;									
				возврат;
			конецесли;
			возврат;
		 конецесли;							
	конеццикла;	
	
	Парм=Новый Структура("Период,ПроверятьНаличиевБД",объект.Период,объект.ПроверятьНаличиевБД);
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить(Парм);
	ФЗ = ФоновыеЗадания.Выполнить("СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник1",МассивПараметров);	
	объект.ФЗ_ВыгрузкаКвитанций = ФЗ.УникальныйИдентификатор;						
	ФЗ2 = ФоновыеЗадания.Выполнить("СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник2",МассивПараметров);	
	объект.ФЗ_ВыгрузкаКвитанций2 = ФЗ2.УникальныйИдентификатор;							
КонецПроцедуры

Т.е. если фоновое уже запущено — то просто получаем его идентификатор и отображаем прогресс бар. Если нет — запускаем

1С: Фоновые задания внутри фоновых заданий

Задача: распаралелить медленную вставку записей в БД 1С, при чтении файла Excel

Как ни странно, но такая возможность есть и работает начиная с версии платформы 8.3.8. Т.е. можно запустить фоновое задание внутри фонового задания….ну например по вставке в БД большого количества записей, которая выполняется весьма медленно. Полноценно этот процесс распаралелить можно например как-то так:

Функция СделатьЗаписьвБДПДЗФоново(парам) экспорт
	...
    // делаем медленную запись в БД
	...
конецфункции	

// Просматриваем массив с идентификаторами фоновых заданий и удаляем те которые завершились
Функция ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий) экспорт
		для каждого ФЗМ из МассивФоновыхЗаданий цикл
			ФЗ = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ФЗМ);
			если ФЗ.Состояние<>СостояниеФоновогоЗадания.Активно тогда
				МассивФоновыхЗаданий.Удалить(МассивФоновыхЗаданий.Найти(ФЗМ));
			конецесли;	
		конеццикла;		
	возврат МассивФоновыхЗаданий;
конецфункции		

// выполняем загрузку построчно файла Excel, запуская запись данных в БД
// отдельным потоком. Количество потоков ограничивам 10 штуками
Функция ВыполнитьЗагрузку(парам) экспорт
	МассивФоновыхЗаданий=Новый Массив();
	МаксимумЗаданий=10;
...
    Для	 нСтрокаТФ = 2 ПО КолВоСтрокФайла Цикл  
        ....
			МассивПараметров = Новый Массив;
			Параметры=Новый Структура("aa,bb,cc",
				1,
				2,
				3,
            );
			МассивПараметров.Добавить(Параметры);
			ФЗ = ФоновыеЗадания.Выполнить("ДлительныеОперации.СделатьЗаписьвБДПДЗФоново",МассивПараметров);	
			МассивФоновыхЗаданий.Добавить(ФЗ.УникальныйИдентификатор);											
			МассивФоновыхЗаданий=ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий);
			// ждём пока завершаться запущеные потоки, если их больше 10
			пока МассивФоновыхЗаданий.Количество()>МаксимумЗаданий цикл
				МассивФоновыхЗаданий=ПочиститьМассивОтЗавершенныхЗаданий(МассивФоновыхЗаданий);
			конеццикла;	        
        ....
   конеццикла;
конецфункции	   

В ниже приведённом каркасе кода, фоново выполняется функция ВыполнитьЗагрузку(), которая читает большой файл Excel, затем каждый цикл вставки записи в БД запускает в свою очередь фоново, ограничивая в данном случае количество фоновых заданий 10 штуками.