Работа с фоновыми заданиями

1. y-ha 01.03.17 19:09 Сейчас в теме
Добрый день!
Изучаю фоновые задания для дальнейшей возможности распараллеливания процессов. Есть простая задача - выгрузить один объект в другие базы через файл.
Реализация выгрузки:
Процедура ВыгрузитьОбъектВXML(Объект, ИмяФайла, МассивПапок) Экспорт
ПолноеИмяФайла = КаталогВременныхФайлов() + ИмяФайла;
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.ОткрытьФайл(ПолноеИмяФайла);
	ЗаписьXML.ЗаписатьОбъявлениеXML();
	ЗаписатьXML(ЗаписьXML, Объект);
	ЗаписьXML.Закрыть();
	Для каждого ПапкаВыгрузки Из МассивПапок Цикл
		МассивПараметров = Новый Массив;
		МассивПараметров.Добавить(Выборка.ПапкаВыгрузки);
		МассивПараметров.Добавить(ИмяФайла);
		МассивПараметров.Добавить(ПолноеИмяФайла);
		Задание = ФоновыеЗадания.Выполнить("МодульТест.СкопироватьФайлВКаталог", МассивПараметров);
		
		МассивЗаданий.Добавить(Задание);
		//СкопироватьФайлВКаталог(Выборка.ПапкаВыгрузки, ИмяФайла, ПолноеИмяФайла); // Вариант без фоновых заданий
	КонецЦикла;
	
	// чтобы удалить файл создадим фоновое задание которое дождется завершения всех заданий и после этого удалит файл
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить(МассивЗаданий);
	МассивПараметров.Добавить(ПолноеИмяФайла);
	Задание = ФоновыеЗадания.Выполнить("МодульТест.ДождатьсяВыполненияФоновыхЗаданийИУдалитьФайл", МассивПараметров);
Конецпроцедуры

Процедура СкопироватьФайлВКаталог(ПапкаВыгрузки, ИмяФайла, ПолноеИмяФайла) Экспорт
	Попытка
		ФайлНаДиске = Новый Файл(ПапкаВыгрузки + "\" + ИмяФайла);
		Если ФайлНаДиске.Существует() Тогда
			Возврат;
		КонецЕсли;
		КопироватьФайл(ПолноеИмяФайла, ПапкаВыгрузки + "\" + ИмяФайла);
	Исключение
		ТекстОшибки = "Ошибка при копировании файла " + ИмяФайла + " в папку: " + ПапкаВыгрузки + символы.ПС + ОписаниеОшибки();
		СообщитьОбОшибке(ТекстОшибки, ПапкаВыгрузки);
	КонецПопытки;
КонецПроцедуры

Процедура ДождатьсяВыполненияФоновыхЗаданийИУдалитьФайл(МассивЗаданий, ПолноеИмяФайла) Экспорт
	
	Если МассивЗаданий.Количество() > 0 Тогда
		Попытка
			ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
			УдалитьФайлы(ПолноеИмяФайла);
		Исключение
		КонецПопытки;
		МассивЗаданий.Очистить();
	КонецЕсли;
	
КонецПроцедуры 

Показать

В результате при запуске фонового задания получаю сообщение:

Ошибка при вызове метода контекста (КопироватьФайл): Ошибка копирования файлов: Ошибка копирования файлов из 'c:\temp\Номенклатура_0034771000002395740.xml' в 'd:\temp\Номенклатура_0034771000002395740.xml' : Файл не обнаружен

Работаю в клиент-серверном варианте. Вызов производится при записи объекта.
права на папку для пользователя, под которым стартует сервер 1с даны (он так же локально работает).
В папке C:\Temp файл с именем Номенклатура_0034771000002395740.xml присутствует.
Если убрать фоновые задания и явно запустить процедуру копирования - то все проходит без ошибок.

В чем еще может быть причина? Куда копать?
По теме из базы знаний
Найденные решения
5. japopov 68 02.03.17 09:37 Сейчас в теме
(1)
Во-первых, у Вас процедура написана так, что работать будет только в винде. Смотрите про ПолучитьРазделительПутиСервера() и ПолучитьРазделительПути().
Во-вторых, есть подозрение, что у Вас мешаются в кучу клиент и сервер: файл создаётся на клиенте, а скопировать пытаетесь на сервере. Или, как минимум, путь строите на клиенте, а использовать его пытаетесь на сервере.

Запустите сервер в режиме отладки (в Сети полно указаний, как). Сделайте автоматическое подключение всего, что можно, и поставьте точку остановки в свою фоновую процедуру, оттрассируйте по шагам.

Наиболее вероятное предположение пока: фоновое задание всегда выполняется на сервере и не имеет контекста. Если Вы запускаете процедуру явно, она выполняется... На сервере или на клиенте? Контекст точно не используется? Ответы проще всего найти трассировкой.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. kuzev 47 01.03.17 19:22 Сейчас в теме
(1) а так проверьте
КопироватьФайл(ПолноеИмяФайла, ПолноеИмяФайла + "1");
3. y-ha 02.03.17 09:24 Сейчас в теме
(2)
КопироватьФайл(ПолноеИмяФайла, ПолноеИмяФайла + "1");

Ошибка та же:
Ошибка при копировании файла Контрагенты_010000000052.xml в папку: D:\Temp\
{ОбщийМодуль.ИнтеграцияЕГАИС.Модуль(8492)}: Ошибка при вызове метода контекста (КопироватьФайл): Ошибка копирования файлов: Ошибка копирования файлов из 'c:\temp\Контрагенты_010000000052.xml' в 'c:\temp\Контрагенты_010000000052.xml1' : Файл не обнаружен

Права на каталог есть (см. приложенный файл).
Прикрепленные файлы:
4. kolya_tlt 86 02.03.17 09:28 Сейчас в теме
(1) вы действительно в xml выгружаете при записи элемента справочника Номенклатура ?
6. y-ha 02.03.17 10:01 Сейчас в теме
(4)
Не понимаю, а какая разница в каком формате сам файл? Расширение - XML. При копировании идет работа с полным именем файла. Что внутри - никак не должно влиять.
7. kolya_tlt 86 02.03.17 10:03 Сейчас в теме
(6) в вопросе нужно было обратить внимание на выгружаете при записи, а не формат файла
9. y-ha 02.03.17 10:11 Сейчас в теме
(7)
Да, вызов процедуры ВыгрузитьОбъектВXML производится в событии При записи в модуле объекта.
15. kolya_tlt 86 02.03.17 10:20 Сейчас в теме
(9) может быть вам предложить сделать очередь выгрузки с рег заданием на саму выгрузку ?
28. igoSolo 9 17.06.19 18:27 Сейчас в теме
(15)
быть вам предложить сделать очередь выгрузки с рег заданием на саму выгрузку

Это для слабаков
5. japopov 68 02.03.17 09:37 Сейчас в теме
(1)
Во-первых, у Вас процедура написана так, что работать будет только в винде. Смотрите про ПолучитьРазделительПутиСервера() и ПолучитьРазделительПути().
Во-вторых, есть подозрение, что у Вас мешаются в кучу клиент и сервер: файл создаётся на клиенте, а скопировать пытаетесь на сервере. Или, как минимум, путь строите на клиенте, а использовать его пытаетесь на сервере.

Запустите сервер в режиме отладки (в Сети полно указаний, как). Сделайте автоматическое подключение всего, что можно, и поставьте точку остановки в свою фоновую процедуру, оттрассируйте по шагам.

Наиболее вероятное предположение пока: фоновое задание всегда выполняется на сервере и не имеет контекста. Если Вы запускаете процедуру явно, она выполняется... На сервере или на клиенте? Контекст точно не используется? Ответы проще всего найти трассировкой.
8. y-ha 02.03.17 10:09 Сейчас в теме
(5)
Работа происходит в обычном приложении. Поэтому про разделитель - не знаю насколько актуально...

Про смешение клиента и сервера мысля понятна. И мысля здравая. Но в моем тестовом примере и клиент и сервер находятся на моей локальной машине. И второй нюанс - в боевом режиме создание новых объектов тоже производится регламентным заданием, поэтому клиент здесь не задействован.

Отладка подключена, но фоновое задание не подключается :( Тут надо танцы с бубном. Наверное придется брать бубен и начинать колдовать.
10. japopov 68 02.03.17 10:15 Сейчас в теме
(8)
Работа происходит в обычном приложении.

Ну, вот мы и нашли Вашу проблему. Толстый клиент, когда выполняете явно и сервер, когда фоновым. Про разделитель - всегда актуально. Хотите, чтобы работало хорошо всё и всегда? Делайте всё и всегда хорошо.


(8)
Про смешение клиента и сервера мысля понятна. И мысля здравая. Н
Ну? А IMHO, это - главная Ваша проблема! Слезайте с обычного приложения, оно сильно вредит культуре программирования. А фоновые именно таковую и требуют. :-)


(8)
Отладка подключена, но фоновое задание не подключается

1) сервер запущен С ПАРАМЕТРОМ ОТЛАДКА?
2) при отладке в Конфигураторе включаете галочки "Автоматическое подключение фоновых заданий"?
Нужно И то, И другое!
17. y-ha 02.03.17 10:21 Сейчас в теме
(10)
Ну? А IMHO, это - главная Ваша проблема! Слезайте с обычного приложения

Конфигурация УТ10.3 построена в обычном приложении.

(10)
Нужно И то, И другое!

Да, это все сделано. Запуск предприятия осуществляется из конфигуратора. Поэтому отладка по умолчанию включена. В сервере дебаг тоже прописан, отладка серверных процедур осуществляется. Но вот с фоновыми заданиями есть нюансы - для того, чтобы к ним подключаться, надо чтобы выполнялся ряд дополнительных условий.
21. japopov 68 02.03.17 10:28 Сейчас в теме
(17)
надо чтобы выполнялся ряд дополнительных условий

Лично я знаю всего два условия... сервер в режиме отладки и автоматическое подключение фоновых заданий в конфигураторе.
24. y-ha 02.03.17 10:33 Сейчас в теме
(21)
Лично я знаю всего два условия... сервер в режиме отладки и автоматическое подключение фоновых заданий в конфигураторе.

ну тогда я подкину в копилку знаний - есть нюанс что база должна быть прописана так же, с точностью до символа и чуть ли не до регистра, как и на самом сервере 1С. т.е. если на сервере указан комп через IP, а на клиенте через имя машины, то отладка не сработает.
26. japopov 68 02.03.17 10:40 Сейчас в теме
(24)
ну тогда я подкину в копилку знаний - есть нюанс что база должна быть прописана так же, с точностью до символа и чуть ли не до регистра, как и на самом сервере 1С. т.е. если на сервере указан комп через IP, а на клиенте через имя машины, то отладка не сработает.

1С 8.3.6+ - таких чудес не заметил.
Впрочем, это и не важно. Давайте стек вызовов: как вызываются Ваши процедуры и какие флажки у модуля. Попробуем сломать всё так, чтобы оно заработало! :-)
27. y-ha 02.03.17 12:46 Сейчас в теме
(26)
Попробуем сломать всё так, чтобы оно заработало! :-)

Спасибо за помощь и участие всем, кто помог. Изначальная проблема, как часто бывает, была по невнимательности, писано в (18) и правильно диагносцирована в (5).
Выношу на общественность новый код, защищенный от проблем клиент/сервера.
Процедура ВыгрузитьОбъектВXML(Объект, ИмяФайла, МассивПапок) Экспорт
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное);
	ОбъектСтрокой = ЗаписьXML.Закрыть();	 


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

Процедура СкопироватьФайлВКаталог(ПапкаВыгрузки, ИмяФайла, ОбъектСтрокой) Экспорт
	
		Текст = Новый ЗаписьТекста(ПапкаВыгрузки + "\" + ИмяФайла, КодировкаТекста.UTF8);
		Текст.Записать(ОбъектСтрокой);
		Текст.Закрыть();
	
КонецПроцедуры

Процедура ЗагрузитьОбъект(ПолноеИмя)
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.ОткрытьФайл(ПолноеИмя);
	НовыйОбъект =  СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
	НовыйОбъект.ОбменДанными.Загрузка = Истина;
	НовыйОбъект.Записать();
	УдалитьФайлы(ТекФайл.ПолноеИмя);
КонецПроцедуры

Показать
13. y-ha 02.03.17 10:18 Сейчас в теме
(5)
Во-первых, у Вас процедура написана так, что работать будет только в винде. Смотрите про ПолучитьРазделительПутиСервера() и ПолучитьРазделительПути().

платформа 8.2.16.352 - про такие методы не знает.
20. japopov 68 02.03.17 10:25 Сейчас в теме
(13) Вам в (15) дело советуют.

Но если уж доделывать то, что есть:

Начните вот с этого:
http://programmist1s.ru/vklyuchenie-otladki-na-servere-1s/

Потом ещё вот тут:
http://programmist1s.ru/otladka-1s/

Включаете отладку фоновых, при условии, что сервер уже запущен в режиме отладки, и ТРАССИРУЕТЕ!!!
Всё просто!
23. y-ha 02.03.17 10:30 Сейчас в теме
(20)
Всё просто!

не все так просто! Все сделано как в тех статьях. режим дебаг включен. галка автоматическое подключение к фоновым заданиям тоже. Для примера можно в инструментах разработчика запустить выполнение фонового задания на сервере - остановка на точке останова происходит. А вот в фоновом задании - нет.
25. spacecraft 02.03.17 10:36 Сейчас в теме
(1) попробуйте убрать запуск фонового задания из цикла. Для одной конкретной папки выгрузки сделать.
И для копирования попробуйте указывать не полный путь:
КопироватьФайл(КаталогВременныхФайлов() + ИмяФайла, ПапкаВыгрузки + "\" + ИмяФайла);

11. YanSergey 145 02.03.17 10:16 Сейчас в теме
Процедура ВыгрузитьОбъектВXML() вызывается на клиенте?. А СкопироватьФайлВКаталог() вызывается на сервере? Соответственно файл должен лежать в каталоге "c:\temp\" самого сервера.
А у вас вероятнее всего он лежит в каталоге "c:\temp\" пользователя
12. japopov 68 02.03.17 10:17 Сейчас в теме
(11) только что написали. Процедура вызывается НЕ на клиенте и НЕ на сервере, а в обычном приложении. То есть, там и то, и другое в куче.
А фоновое, естественно, только на сервере.
14. YanSergey 145 02.03.17 10:18 Сейчас в теме
(12) Если в обычном приложении, значит на клиенте.
16. japopov 68 02.03.17 10:21 Сейчас в теме
(14) ну, не совсем. На клиенте с возможностью серверных вызовов. Короче, каша.
19. YanSergey 145 02.03.17 10:24 Сейчас в теме
(16) Ну я имею ввиду что файл записывается во временный каталог ПОЛЬЗОВАТЕЛЯ под которым запущен сеанс.
А фоновое задание, поскольку выполняется на сервере, то оно ищет файл в каталоге "c:\temp\" самого сервера, файла там естественно нет.
Надо помещать файл в какой то общий сетевой каталог, к которому есть доступ как с клиентских машин, так и с сервера.

Добавлено: ну раз одна машина, тогда пардон )))
18. y-ha 02.03.17 10:23 Сейчас в теме
(11)
А у вас вероятнее всего он лежит в каталоге "c:\temp\" пользователя

Да, с третьего раза дошло!
Есть две базы, одна на локальном сервере, вторая на удаленном сервере! Вот тут и зарылась собака! Сейчас тестирую на удаленном сервере, поэтому действительно запись объекта производится в толстом клиенте, а фоновое задание - на сервере! Причина в этом.
22. japopov 68 02.03.17 10:30 Сейчас в теме
Вообще, Вы, давайте, с самого начала опишите. Мне кажется, у Вас проблема растёт из того, как всё вызывается.
МодульТест какие флажки имеет?
Как сделали подключение к событию ПриЗаписи? От какого объекта: от формы, от справочника, подпиской?
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот