Фоновые задания в файловом режиме 1С 8.x средствами 1С без дополнительных компонент

19.05.10

Разработка - Механизмы платформы 1С

Необходимость использования фоновых задач в файловом варианте есть, а вот возможность это осуществить - совсем не очевидна.
Можно конечно воспользоваться дополнительными Active-X компонентами (http://infostart.ru/public/66660/) или запускать две копии приложения. Я же нашел (как мне) кажется более простой и гибкий вариант и при этом все только средствами самой 1С.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Фоновые задания в файловой среде
.dt 14,44Kb
201
201 Скачать (1 SM) Купить за 1 850 руб.

Понадобилось мне в фоне длительные операции делать и при этом, чтобы пользователь мог спокойно работать с программой. В 8.1 появились фоновые задания, которые предназначены как раз для этой цели. Но оказывается всё не так просто. Всё хорошо в клиент\серверном варианте, а вот в файловом...

Для того чтобы можно было выполнять фоновые задания необходимо, чтобы:

  1. До запуска фонового задания была вызвана процедура "ВыполнитьОбработкуЗаданий()"
  2. Для собственно выполнения заданий должна периодически вызываться процедура ВыполнитьОбработкуЗаданий()

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

При Com-соединении вызывать эту процедуру тоже без толку, так как опять таки синхронная работа (ожидание вызывающим вызываемого).

 Но оказывается из этого замкнутого круга есть выход.

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

Я сделал так:

  1. Добавил специального пользователя Server (в списке не выводить)
  2. Определил глобальную экспортную переменную V8Com в модуле приложения .
  3. В модуле приложения добавил следующий код:

Перем V8Com Экспорт;

Процедура
ПередНачаломРаботыСистемы(Отказ)
    Если
ИмяПользователя() = "Server" тогда
       
ПодключитьОбработчикОжидания("ОбработчикОжидания",1);
    КонецЕсли;
КонецПроцедуры

Процедура
ОбработчикОжидания() экспорт
   
ВыполнитьОбработкуЗаданий();
КонецПроцедуры

Если обрабатывать фоновые задания необходимо сразу, а не по специальному требованию пользователя, то можно прямо в модуле приложения добавить:

V8Com = Новый COMОбъект("V81.Application");

Попытка
   
Открытие = V8Com.Connect(СтрокаСоединенияИнформационнойБазы()+ "Usr=""Server"";Pwd=""123"";");
Исключение
   
Предупреждение("Ошибка открытия фоновой копии!!!");
   
Отказ = истина;
    Возврат;
КонецПопытки;

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

После можно запускать фоновые задания штатными методами. 

Например:

ФоновыеЗадания.Выполнить("ОбработкаФоновыхЗаданий.ВыполнитьЦикл", МассивПараметров,"Индикатор2");

В демонстрационной обработке можно посмотреть как это работает.

За основу обработки я взял обработку отсюда.

Кое-что правда не удалось (по крайней мере пока):

  1. Не получилось использовать обработчики событий для обмена данными между фоновой копией и основной. Не ясно какое и как событие генерировать в фоновой функции и как его потом ловить в главном приложении. (если кто знает, подскажите). В демонстрационной конфигурации передача данных происходит через регистр сведений. 
  2. Задания выполняются не параллельно, а по очереди. Судя по всему причина такого поведения в особенностях работы процедуры ВыполнитьОбработкуЗаданий() внутри Обработчика ожидания. То ли обработчик ожидания не прерывается (активности пользователя ведь для фоновой копии быть не может), то ли просто выполнение заданий задумано так.  

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

P.S. Если такое решение "всем известно", то прошу меня сильно не бить, так как я еще неделю назад активно искал решение но не нашел. Вариант с внешней Active-X компонентой у меня не заработал.      

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

23.06.2024    7457    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5946    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    17673    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11225    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23763    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18832    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    14734    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Evg-Lylyk 4841 19.05.10 12:36 Сейчас в теме
2. kosilov 276 19.05.10 22:05 Сейчас в теме
(1) Да, это тоже вариант. Но в моем варианте используется стандартный механизм фоновых заданий. Ком соединие используется только для того, чтобы выполнять задания, т.е. запускать стандартную функцию "выполнить задания".
3. kosilov 276 19.05.10 22:20 Сейчас в теме
Вот тут пишут человек, что штатными способами вернуть результат работы невозможно из фонового задания. Для клиент\серверного варианта наверное действительно только через базу (хотя можно изучить возможность через временую таблицу).
Для файлового варианта, интуитивно чувствую что как-то можно через нотификации. Я просто немного запутался в них. Есть внешник, а есть внутренние, есть еще каие-то функции установки обработчиков. Что с чем стыкуется и какова "видимость" мне пока не ясно. Если есть кто на этом собаку съел поделитесь опытом.
Суть вопроса в следующем:
1. Как сгенерировать сообщение (событие, нотификацию) в 1С, которое передасться через ком соединение вызывающем приложению. Т.е. Чтобы его можно было поймать как в данном стандартном примере:
msword = New COMObject("Word.Application");
AddHandler msword.DocumentChange, WhenDocumentChange
Procedure WhenDocumentChange()
	Message("Document is changed");
EndProcedure 


2. Как другим сопсобом сгенерить сообщение (например Notify - уведомить), чтобы как-то его отловить в другом сообщении.
4. kosilov 276 19.05.10 22:36 Сейчас в теме
(3) И вот еще как можно передать данные при данном варианте от отработавшего задания:
1. В глобальном модуле определяем переменную:
Перем РезультатыФоновойРаботы Экспорт;

А потом в конце:
РезультатыФоновойРаботы = новый Соответствие;

Плюс функция:
Функция ВернутьРезультатФоновогоЗадания(Ключ) Экспорт
 Рез = РезультатыФоновойРаботы[Ключ];
 РезультатыФоновойРаботы.Удалить(Ключ);
возврат Рез;
конецфункции


При выполнении фонового задания, фоновая функция должна знать свой ключ, т.е. его надо передавать ей параметром.
После выполнения функции перед конецфункции пишем:
РезультатыФоновойРаботы[Ключ] = <Наш результат работы в виде чего угодно>

И вуаля:
Запускаем фоновое задание. Отслеживаем его завершение через стандартный механизм: ФоновыеЗаданияПолучитьФоновыеЗадания или ФоновыеЗадания.НайтиПоУникальномуИдентификатору.
А затем обращаемся к наему глобальному ком объекту.
Рез = V8Com.ВернутьРезультатФоновогоЗадания(Ключ);
В данном случае это будет синхронный вызов и мы получим результат.

Мне кажется, что это элегантно.
5. Душелов 4018 25.05.10 18:03 Сейчас в теме
Кстати, обычные фоновые задания довольно часто зависают. Решения проблемы так и не нашли - только перезапуск сервиса.
6. kosilov 276 26.05.10 00:56 Сейчас в теме
(5) Пока не сталкивался. А как виснут? В смысле виснет среда?
А что 1С по этому поводу говорит?
7. Душелов 4018 26.05.10 01:05 Сейчас в теме
(6) В смысле то, что фоновое задание висит бесконечно со статусом "выполняется" и никак его не удалить, ни через консоль заданий, ни через консоль серверов, что в 8.1, что в 8.2 встречается. Поэтому и пришлось писать свою компоненту для многопоточности.
8. sas2006 29.10.10 15:12 Сейчас в теме
У у меня появился вопрос, получается будет запускаться еще одна копия 1с и следовательно должна быть еще одна свободная лицензия?
9. Kazan 12.10.11 06:14 Сейчас в теме
не понятно какой конкретно оператор запускает механизм выполнения заданий от имени сервера - ВыполнитьОбработкуЗаданий или оновыеЗадания.Выполнить ???
10. krevedgo 27.12.12 23:03 Сейчас в теме
Спасибо автору за тему!
Очень нужная вещь, но...
Помогите плиз начинающему
Что куда вписывать? Платформа 8.2
Открыл конфигуратор, открыл модуль управляемого приложения
Сделал так:
// Конец СтандартныеПодсистемы
Перем V8Com Экспорт;

Процедура ПередНачаломРаботыСистемы(Отказ)
	
	// СтандартныеПодсистемы
	СтандартныеПодсистемыКлиент.ДействияПередНачаломРаботыСистемы(Отказ);
	// Конец СтандартныеПодсистемы
	
	//выполняем фоновые задания
если ИмяПользователя() = "Server" тогда
       ПодключитьОбработчикОжидания("ОбработчикОжидания",1);
   КонецЕсли;
   //конец выполняем фоновые задания

	
КонецПроцедуры

 Процедура ОбработчикОжидания() экспорт
       ВыполнитьОбработкуЗаданий();
 КонецПроцедуры

Процедура ПриНачалеРаботыСистемы()
	
	НеобходимаНачальнаяНастройкаПрограммы = ОбновлениеИнформационнойБазыУТ.НеобходимаНачальнаяНастройкаПрограммы();
	
	// СтандартныеПодсистемы
	СтандартныеПодсистемыКлиент.ДействияПриНачалеРаботыСистемы(Истина);
	// Конец СтандартныеПодсистемы
	
	//Диалог выбора варианта настройки системы
	Если НеобходимаНачальнаяНастройкаПрограммы Тогда
		ОткрытьФормуМодально("ОбщаяФорма.ВыборВариантаНастройкиПрограммы");
	КонецЕсли;
	//Конец Диалог выбора варианта настройки системы
	
	//ОткрытиеФормПриНачалеРаботыСистемы
	ОткрытиеФормПриНачалеРаботыСистемыКлиент.ПриНачалеРаботыСистемы();
	//Конец ОткрытиеФормПриНачалеРаботыСистемы
	
	V8Com = Новый COMОбъект("V81.Application");

 Попытка
     Открытие = V8Com.Connect(СтрокаСоединенияИнформационнойБазы()+ "Usr=""Server"";Pwd=""123"";");
 Исключение
     Предупреждение("Ошибка открытия фоновой копии!!!");
     Отказ = истина;
     Возврат;
 КонецПопытки;

КонецПроцедуры

Показать


Запускаю отладку и получаю ошибку
{МодульУправляемогоПриложения(97)}: Ошибка при вызове конструктора (COMОбъект)
V8Com = Новый COMОбъект("V81.Application");
по причине:
Недопустимая строка с указанием класса


Попробовал это - не помогло.

Подскажите, что я делаю не так?
Смущает "СтрокаСоединенияИнформационнойБазы" - может тут должно быть что-то более конкретное?
Требуется выполнять всего одно задание "обмен с сайтом", как-то в УТ10 это работало без дополнительной химии, а вот в УТ11 уже не получается.
11. nikbrik 07.02.13 16:50 Сейчас в теме
(10)
Что куда вписывать? Платформа 8.2
V8Com = Новый COMОбъект("V81.Application");

Ответ очевиден:
V8Com = Новый COMОбъект("V82.Application");

Вопрос: метод работает, фоновые задания выполняются, НО необходимо фоновым заданием принудительно завершить работу пользователя в определенное время. Если запускал от имени текущего пользователя - все работало, но с этим методом вообще ничего не происходит. Может нашли уже какой-то способ передать сообщение о выполнении задания?
12. kosilov 276 07.02.13 17:43 Сейчас в теме
Уже не припомню.

Но как крайний вариант, сделайте так:
1. Создайте регистр сведений или используйте какой-то предопределенный элемент БД, который синхронизируется между разными потоками.
2. На клиентком процессе сделайе регулярный опрос ( каждый 30 сек например) этого регистра (или эл-та который вы использовали).
3. Если фоновый поток требует завершения пользователей,то в БД выставляется флаг (в этот ваш эл-т или регистр)
4. Клиентский поток смотрит это значение и если там стоит флаг завершения, то клиентский поток сам завершается по собственному т.с. желанию.

Если, я конечно правильно понял вашу задачу.
13. nikbrik 07.02.13 17:58 Сейчас в теме
(12)Спасибо за ответ
Дело в том, что фоновый процесс нужен был, чтобы в файловом варианте не мешать работе пользователя постоянными проверками фоновых заданий. А то что вы предлагаете - значит опять проверять каждые 30 секунд на наличие флага) опять будут подвисания, тогда просто нет смысла в фоновом процессе... Или может я ошибаюсь, и есть способ проверять на наличие флага как-то незаметно?
P.S. Извините что не могу более ясно выражать мысли)) после работы голова гудит...
14. kosilov 276 07.02.13 19:15 Сейчас в теме
Я пробовал играться с нотификациями, но что-то не очень у меня это получилось.

У вас таймаут большой может быть (будет не критично) 30 сек или минута.
Там есть хэндлер (к сожалению уже не помню название) который может быть вызван только тогда когда нет активности на стороне пользователя. Если вы используете этот метод, то пользователь не будет замечать что система что-то опрашивает.
15. sanfoto 502 13.01.15 13:26 Сейчас в теме
(0) отказался я от "COM-Объектов" и от ВыполнитьОбработкуЗаданий()

т.к. нужно было реализовать запуск независящий запуск от действий пользователя - пришлось использовать обработчики в ПриНачалеРаботыСистемы(), и порой на компе на котором это использовалось... плодились несколько COM-Объектов.... все работало и пользователю практически не мешало, но память съедалась(((

***************РЕШЕНИЕ - использовать ИСКЛЮЧИТЕЛЬНО "ФоновыеЗадания" а не их инициализацию через "РегламентныеЗадания" ****************

Процедура ПриНачалеРаботыСистемы()
//.............Некий код.
//.............Некий код
ПодключитьОбработчикОжидания("ФоновоеЗаданиеТранзакцииКафеЧерезВебСервисВ_УПП_ТекущиеПрод­ажи", 30);
//.............Некий код
//.............Некий код
КонецПроцедуры

Процедура ФоновоеЗаданиеТранзакцииКафеЧерезВебСервисВ_УПП_ТекущиеПрода­жи() Экспорт
	ПараметрыОтбора = Новый Структура("Наименование, Статус", "ФоновоеЗаданиеТранзакцииКафеЧерезВебСервисВ_УПП_ТекущиеПрод­ажи", СостояниеФоновогоЗадания.Активно);	
	СписокФоновыхЗаданий = ФоновыеЗадания.ПолучитьФоновыеЗадания(ПараметрыОтбора);
	
	Если СписокФоновыхЗаданий.Количество()>0 Тогда
		Если СписокФоновыхЗаданий[0].Состояние = СостояниеФоновогоЗадания.Активно Тогда
			Возврат;
		КонецЕсли;		
	КонецЕсли;
//.............Некий код
//.............Некий код
КонецПроцедуры
Показать
16. freeek 10.03.15 16:36 Сейчас в теме
Здравствуйте! Подскажите, пожалуйста. Сталкивался кто-нибудь с такой проблемой, как "потеря пользователя" после выполнения фонового задания. Проверяю так:

МассивСоединений = ПолучитьСоединенияИнформационнойБазы();
Для Каждого ТекСоединение Из МассивСоединений Цикл

значение "ТекСоединение.Пользователь" именно текущего пользователя пустое.
Почему до выполнения фоновых заданий все норм, а после выполнения любого первого, как бы "теряется текущий пользователь"?
17. dctvghbdtn 19.10.21 20:12 Сейчас в теме
В файловом режиме фоновые задания выполняются последовательно? Следующее не начнется пока не завершится предыдущее?
18. tyazhovkin 03.04.24 05:00 Сейчас в теме
(17) Да

Файловая база

Задания выполняются по мере завершения другого задания.
Если запустить последовательно 3 задания 60, 15 и 1 секунды, они выполнятся в порядке 60, 15, 1

Клиент-сервер

Задания выполняются параллельного друг другу.
Если запустить последовательно 3 задания 60, 15 и 1 секунды, они выполнятся в порядке 1, 15, 60
Оставьте свое сообщение