В платформе версией до 8.3.9.1818 для обычных форм существует следующая ошибка:
Строка "ПоместитьВоВременноеХранилище(Данные, АдресХранилища);" выполняется мгновенно, но сам результат может быть помещен во временное хранилище со значительной задержкой. В статье описан простой вариант обхода данной ошибки.
Периодически результат выполнения фонового задания долго помещается во временное хранилище, при этом само фоновое задание уже не активно. Найденные способы решения: переписать на управляемых формах, обновить платформу, использовать общую форму "ДлительнаяОперация" из БСП. Если описанные решения не подходят, то существует ещё один вариант (упоминаний о нём не нашел).
Рассмотрим следующий пример - в конфигурации присутствует отчёт, часть данных для которого формируется в фоновом задании. Стандартно в форме отчёта запускается обработчик ожидания, в котором проверяется состояние фонового задания. При успешном завершении по адресу временного хранилища должны быть данные с результатом работы задания, но "появиться" они там могут с задержкой. Для решения проблемы можно передать представление результата работы задания в тексте сообщения (используя функцию ЗначениеВСтрокуВнутр).
Строка "ПоместитьВоВременноеХранилище(Данные, АдресХранилища);" выполняется мгновенно, но сам результат может быть помещен во временное хранилище со значительной задержкой. В статье описан простой вариант обхода данной ошибки.
Периодически результат выполнения фонового задания долго помещается во временное хранилище, при этом само фоновое задание уже не активно. Найденные способы решения: переписать на управляемых формах, обновить платформу, использовать общую форму "ДлительнаяОперация" из БСП. Если описанные решения не подходят, то существует ещё один вариант (упоминаний о нём не нашел).
Рассмотрим следующий пример - в конфигурации присутствует отчёт, часть данных для которого формируется в фоновом задании. Стандартно в форме отчёта запускается обработчик ожидания, в котором проверяется состояние фонового задания. При успешном завершении по адресу временного хранилища должны быть данные с результатом работы задания, но "появиться" они там могут с задержкой. Для решения проблемы можно передать представление результата работы задания в тексте сообщения (используя функцию ЗначениеВСтрокуВнутр).
Код работы с фоновым заданием в основной форме отчёта:
// Формирует данные для отчета в фоновом задании
Процедура ПолучитьДанныеВФоне( МассивДляОбработки )
// модуль "ДлительныеОперации" из БСП в редакции, которая используется в конфигурации УПП
// мУИДФормы - переменная формы с типом УникальныйИдентификатор
РезультатВыполнения = ДлительныеОперации.ЗапуститьВыполнениеВФоне( мУИДФормы, "ФормированиеДанныхОтчетаСервер.ПолучитьДанныеВФоне"
, Новый Структура("МассивДляОбработки", МассивДляОбработки), НСтр("ru = 'Получение данных для отчёта'") );
мАдресВоВременномХранилище = РезультатВыполнения.АдресХранилища;
мУИДФоновогоЗадания = РезультатВыполнения.ИдентификаторЗадания;
Подключаемый_ПроверитьВыполнениеЗадания();
КонецПроцедуры
Процедура Подключаемый_ПроверитьВыполнениеЗадания()
ЗапускатьОбработчикОжидания = Истина;
Попытка
Если ДлительныеОперации.ЗаданиеВыполнено(мУИДФоновогоЗадания) Тогда
РезультатФоновогоЗадания = ПолучитьИзВременногоХранилища(мАдресВоВременномХранилище);
// по факту задание может быть завершено, но данные во временное хранилище не помещены
Если ЗначениеЗаполнено(РезультатФоновогоЗадания) Тогда
ЗапускатьОбработчикОжидания = Ложь;
// ... обработка результата по данным из временного хранилища
Иначе
Если Не ПустаяСтрока(мДанныеСтрокаВнутр) Тогда
ЗапускатьОбработчикОжидания = Ложь;
РезультатФоновогоЗадания = ЗначениеИзСтрокиВнутр(мДанныеСтрокаВнутр);
// ... обработка результата по данным из мДанныеСтрокаВнутр
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
ВызватьИсключение; // вывод информации об ошибке реализован в вызове ДлительныеОперации.ЗаданиеВыполнено
КонецПопытки;
Если ЗапускатьОбработчикОжидания Тогда
ТекПроцентВыполненияСтрокой = "";
ЗаполнитьПроцентВыполнения(мУИДФоновогоЗадания, ТекПроцентВыполненияСтрокой);
// ... вывод информации о ходе выполнения
ПодключитьОбработчикОжидания("Подключаемый_ПроверитьВыполнениеЗадания", 2, Истина);
Иначе
УдалитьИзВременногоХранилища(мАдресВоВременномХранилище);
КонецЕсли;
КонецПроцедуры
// Сохраняет прогресс в переменную ПроцентВыполненияСтрокой. Для сообщений, текст которых начинается
// с "{" - сохраняет данные в переменную мДанныеСтрокаВнутр
Процедура ЗаполнитьПроцентВыполнения(ИдентификаторЗадания, ПроцентВыполненияСтрокой)
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание = Неопределено Тогда Возврат; КонецЕсли;
МассивСообщений = Задание.ПолучитьСообщенияПользователю(Истина);
Если МассивСообщений = Неопределено Тогда Возврат; КонецЕсли;
Для Каждого Сообщение Из МассивСообщений Цикл
Если Строка(Сообщение.ИдентификаторНазначения) = "00000000-0000-0000-0000-000000000000" Тогда
Если Лев(Сообщение.Текст, 1) <> "{" Тогда
ПроцентВыполненияСтрокой = Сообщение.Текст + "%";
Иначе
мДанныеСтрокаВнутр = Сообщение.Текст;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если НЕ Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
ПроцентВыполненияСтрокой = "100%";
КонецЕсли;
КонецПроцедуры
Код серверного неглобального модуля "ФормированиеДанныхОтчетаСервер":
Процедура ПолучитьДанныеВФоне(Параметры, АдресХранилища) Экспорт Результат = Новый Соответствие; МассивДляОбработки = Параметры.МассивДляОбработки; ВсегоЗаписей = МассивДляОбработки.Количество(); Для ТекИндекс = 0 По ВсегоЗаписей - 1 Цикл // ... код обработки элементов массива, заполнение переменной Результат // формирование прогресса выполнения в родительском сеансе ПроцентВыполнения = Окр( (ТекИндекс + 1) * 100 / ВсегоЗаписей); ОбщегоНазначенияКлиентСервер.СообщитьПользователю( Строка(ПроцентВыполнения) ); КонецЦикла; // отправим результат работы фонового задания в сообщении для обработки в родительском сеансе ОбщегоНазначенияКлиентСервер.СообщитьПользователю( ЗначениеВСтрокуВнутр(Результат) ); // строка ниже выполняется мгновенно, но сам результат может быть помещен во временное хранилище со значительной задержкой ПоместитьВоВременноеХранилище(Результат, АдресХранилища); КонецПроцедуры
Если знаете другие варианты борьбы с данной ошибкой - просьба написать в комментариях.
Код серверного неглобального модуля "ФормированиеДанныхОтчетаСервер":
Процедура ПолучитьДанныеВФоне(Параметры, АдресХранилища) Экспорт Результат = Новый Соответствие; МассивДляОбработки = Параметры.МассивДляОбработки; ВсегоЗаписей = МассивДляОбработки.Количество(); Для ТекИндекс = 0 По ВсегоЗаписей - 1 Цикл // ... код обработки элементов массива, заполнение переменной Результат // формирование прогресса выполнения в родительском сеансе ПроцентВыполнения = Окр( (ТекИндекс + 1) * 100 / ВсегоЗаписей); ОбщегоНазначенияКлиентСервер.СообщитьПользователю( Строка(ПроцентВыполнения) ); КонецЦикла; // отправим результат работы фонового задания в сообщении для обработки в родительском сеансе ОбщегоНазначенияКлиентСервер.СообщитьПользователю( ЗначениеВСтрокуВнутр(Результат) ); // строка ниже выполняется мгновенно, но сам результат может быть помещен во временное хранилище со значительной задержкой ПоместитьВоВременноеХранилище(Результат, АдресХранилища); КонецПроцедуры
Если знаете другие варианты борьбы с данной ошибкой - просьба написать в комментариях.
Комментариев нет:
Отправить комментарий