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

19.05.10

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

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

Скачать файлы

Наименование Файл Версия Размер
Фоновые задания в файловой среде
.dt 14,44Kb
201
.dt 14,44Kb 201 Скачать

Понадобилось мне в фоне длительные операции делать и при этом, чтобы пользователь мог спокойно работать с программой. В 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 компонентой у меня не заработал.      

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4547    dsdred    53    

72

Как готовить и есть массивы

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

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

24.01.2024    5298    YA_418728146    25    

63

Планы обмена VS История данных

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

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

11.12.2023    6412    dsdred    36    

112

1С-ная магия

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

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

06.10.2023    18480    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

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

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

14.09.2023    12094    human_new    27    

74

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    8831    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

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

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6283    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

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

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15989    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Evg-Lylyk 4580 19.05.10 12:36 Сейчас в теме
2. kosilov 275 19.05.10 22:05 Сейчас в теме
(1) Да, это тоже вариант. Но в моем варианте используется стандартный механизм фоновых заданий. Ком соединие используется только для того, чтобы выполнять задания, т.е. запускать стандартную функцию "выполнить задания".
3. kosilov 275 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 275 19.05.10 22:36 Сейчас в теме
(3) И вот еще как можно передать данные при данном варианте от отработавшего задания:
1. В глобальном модуле определяем переменную:
Перем РезультатыФоновойРаботы Экспорт;

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

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


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

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

Мне кажется, что это элегантно.
5. Душелов 4014 25.05.10 18:03 Сейчас в теме
Кстати, обычные фоновые задания довольно часто зависают. Решения проблемы так и не нашли - только перезапуск сервиса.
6. kosilov 275 26.05.10 00:56 Сейчас в теме
(5) Пока не сталкивался. А как виснут? В смысле виснет среда?
А что 1С по этому поводу говорит?
7. Душелов 4014 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 275 07.02.13 17:43 Сейчас в теме
Уже не припомню.

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

Если, я конечно правильно понял вашу задачу.
13. nikbrik 07.02.13 17:58 Сейчас в теме
(12)Спасибо за ответ
Дело в том, что фоновый процесс нужен был, чтобы в файловом варианте не мешать работе пользователя постоянными проверками фоновых заданий. А то что вы предлагаете - значит опять проверять каждые 30 секунд на наличие флага) опять будут подвисания, тогда просто нет смысла в фоновом процессе... Или может я ошибаюсь, и есть способ проверять на наличие флага как-то незаметно?
P.S. Извините что не могу более ясно выражать мысли)) после работы голова гудит...
14. kosilov 275 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 Сейчас в теме
В файловом режиме фоновые задания выполняются последовательно? Следующее не начнется пока не завершится предыдущее?
Оставьте свое сообщение