Имя: Пароль:
1C
1С v8
СообщениеПользователю и фоновый режим
0 Nicole
 
07.05.20
14:39
Есть некая длительная обработка, которая запускается в фоновом режиме. В ходе обработки перезаписываются документы (наподобие ГрупповогоИзмененияРеквизитов). В процедуре ПередЗаписью() выполняется ряд проверок и выводятся сообщения ОбщегоНазначенияКлиентСервер.СообщитьПользователю("");
Так вот в режиме отладки эти сообщения после окончания длительной обработки выводятся на экран. В обычном пользовательском режиме - нет.
Пробовала воспользоваться функцией ДлительныеОперации.СообщенияПользователю() - то же самое: в режиме отладки возвращаются накопленные сообщения в фиксированном массиве, в обычном пользовательском режиме массив пустой.

Что и как сделать, чтобы все-таки получить и вывести накопленные в ходе длительной обработки сообщения?
Спасибо.
1 Franchiser
 
гуру
07.05.20
15:25
У ФЗ есть свойство в котором можно прочитать сообщения все. Через эти сообщения в БСП и реализована передача прогресса.
2 Franchiser
 
гуру
07.05.20
15:28
Задание.ПолучитьСообщенияПользователю()
3 Nicole
 
07.05.20
15:32
(2) Возвращается пустое в пользовательском режиме. В режиме отладки - со всеми сообщениями.
4 Garykom
 
гуру
07.05.20
15:35
(0)
1. Писать в журнал регистрации и не страдать не пойми чем
2. Если фоновое запущено на сервере 1С, причем оно может работать даже когда ни одного клиента нет то?
Обработка ожидания на клиенте и читай периодически сообщения (каким образом пофиг) которые фоновое куда то пишет.
5 Franchiser
 
гуру
07.05.20
15:37
В режиме отладки у тебя обработка работает без ФЗ?
Ты уверен что именно используешь ФЗ.Получитьсообщенияпользователю(), а не просто Получитьсообщенияпользователю()?
К меня выводятся сообщения по многопоточным обработкам.
6 Franchiser
 
гуру
07.05.20
15:38
Я опрашивпю состояние фонового задания и считываю сообщения по мере проверки в отдельный массив.
7 Nicole
 
07.05.20
15:51
(5) ФЗ.ПолучитьСообщенияПользователю() - это тоже пустое.
8 Franchiser
 
гуру
07.05.20
16:00
(7) в каком  момент ты проверяешь сообщения? Нужно проверять на клиенте каждый раз, когда выполняется проверка завешения ФЗ.
9 Franchiser
 
гуру
07.05.20
16:02
Сообщ = ФЗ.ПолучитьСообщенияПользователю();
10 Nicole
 
07.05.20
16:03
Не может быть дело в том, что в процедуре ПередЗаписью() после сообщения пользователю идет "Отказ=Истина;" и в ходе выполнения ФЗ срабатывает исключение?
11 Franchiser
 
гуру
07.05.20
16:05
Нет, у меня даже если возникает ошибка записи видны все сообщения проведения.
12 Franchiser
 
гуру
07.05.20
16:07
Если в ФЗ возникла необработанная исключительная ситуация то будет аварийное завершение ФЗ.
13 Nicole
 
07.05.20
16:10
(8) На клиенте? Для метода ФоновоеЗадание.ПолучитьСообщенияПользователю() написано, что он доступен на сервере...
14 Franchiser
 
гуру
07.05.20
16:12
(13) в обработке ожидания клиента вызывай метод на сервере
15 Franchiser
 
гуру
07.05.20
16:17
Считывает информацию о ходе выполнения фонового задания и сообщения, которые в нем были сформированы.
//
// Параметры:
//   ИдентификаторЗадания - УникальныйИдентификатор - идентификатор фонового задания.
//   Режим                - Строка - "ПрогрессИСообщения", "Прогресс" или "Сообщения".
//
// Возвращаемое значение:
//   Структура - со свойствами:
//    * Прогресс  - Неопределено, Структура - Информация о ходе выполнения фонового задания, записанная процедурой СообщитьПрогресс:
//     ** Процент                 - Число  - Необязательный. Процент выполнения.
//     ** Текст                   - Строка - Необязательный. Информация о текущей операции.
//     ** ДополнительныеПараметры - Произвольный - Необязательный. Любая дополнительная информация.
//    * Сообщения - ФиксированныйМассив - Массив объектов СообщениеПользователю, которые были сформированы в фоновом задании.
//
Функция ПрочитатьПрогрессИСообщения(Знач ИдентификаторЗадания, Знач Режим = "ПрогрессИСообщения")
    
    Сообщения = Новый ФиксированныйМассив(Новый Массив);
    Результат = Новый Структура("Сообщения, Прогресс", Сообщения, Неопределено);
    
    Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
    Если Задание = Неопределено Тогда
        //Сообщить("НЕТ ЗАДАНИЯ");
        Возврат Результат;
    КонецЕсли;
    
    МассивСообщений = Задание.ПолучитьСообщенияПользователю(Истина);
    Если МассивСообщений = Неопределено Тогда
         //Сообщить("НЕТ СООБЩЕНИЙ");

        Возврат Результат;
    КонецЕсли;
    
    Количество = МассивСообщений.Количество();
    //Сообщить("Количество сообщений прогресса" +Количество);
    Сообщения = Новый Массив;
    ЧитатьСообщения = (Режим = "ПрогрессИСообщения" Или Режим = "Сообщения");
    ЧитатьПрогресс  = (Режим = "ПрогрессИСообщения" Или Режим = "Прогресс");
    
    Если ЧитатьСообщения И Не ЧитатьПрогресс Тогда
        Результат.Сообщения = Новый ФиксированныйМассив(МассивСообщений);
        Возврат Результат;
    КонецЕсли;
    
    Для Номер = 0 По Количество - 1 Цикл
        Сообщение = МассивСообщений[Номер];
        
        Если ЧитатьПрогресс И СтрНачинаетсяС(Сообщение.Текст, "{") Тогда
            //Сообщение.Сообщить(); //+SAV отладка...
            Позиция = СтрНайти(Сообщение.Текст, "}");
            Если Позиция > 2 Тогда
                ИдентификаторМеханизма = Сред(Сообщение.Текст, 2, Позиция - 2);
                Если ИдентификаторМеханизма = ДлительныеОперации.СообщениеПрогресса() Тогда
                    ПолученныйТекст = Сред(Сообщение.Текст, Позиция + 1);
                    Результат.Прогресс = ОбщегоНазначения.ЗначениеИзСтрокиXML(ПолученныйТекст);
                    Продолжить;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        Если ЧитатьСообщения Тогда
            Сообщения.Добавить(Сообщение);
        КонецЕсли;
    КонецЦикла;
    
    Результат.Сообщения = Новый ФиксированныйМассив(Сообщения);
    Возврат Результат;
    
КонецФункции
16 Franchiser
 
гуру
07.05.20
16:19
Далее:

Сообщения = ПрогрессИСообщения.Сообщения;
    
    Для Каждого Сбщ из Сообщения Цикл
        МассивСообщений.Добавить(Сбщ);
        Сбщ.сообщить();    
    КонецЦикла;
17 Nicole
 
07.05.20
16:27
Я вызываю ДополнительныеОперации.ВыполнитьВФоне(). В конце этой функции есть обращение к ПрочитатьПрогрессИСообщения().

ПрогрессИСообщения = ПрочитатьПрогрессИСообщения(Задание.УникальныйИдентификатор, "ПрогрессИСообщения");
Результат.Сообщения = ПрогрессИСообщения.Сообщения;

И Результат.Сообщения всегда пустое.
18 fisher
 
07.05.20
16:41
(17) Вот тут где-то собака и порылась. БСП вычитывает сообщения с удалением. И при этом выдает только "свои" сообщения прогресса (которые в фигурных скобках, посылаемые через СообщитьПрогресс).
19 fisher
 
07.05.20
16:42
В общем, которые ты посылала не через СообщитьПрогресс() - благополучно прибились.
20 Franchiser
 
гуру
07.05.20
16:43
Так у тебя только 1 раз выполнится.

А должен быть еще код вида для постоянного опроса и там тоже вызывается эта процедура:
ДлительныеОперацииКлиент.ОбновитьПараметрыОбработчикаОжидания(ПараметрыОбработчикаОжиданияДлительнойОперации);
ПодключитьОбработчикОжидания("ФоновоеПроверитьНаКлиенте", ПараметрыОбработчикаОжиданияДлительнойОперации.ТекущийИнтервал, Истина);
21 Franchiser
 
гуру
07.05.20
16:46
ПодключитьОбработчикОжидания("ВыполнитьДлительнуюОперациюКлиент",0.1,Истина);
22 Franchiser
 
гуру
07.05.20
16:49
(17) (18) по этой причине, чтобы не прибивались сообщения в процедуре и т.к. она не экспортная, процедуру нужно скопировать в твою обработку.
23 fisher
 
07.05.20
16:49
А в режиме отладки выводится потому что БСП в ДополнительныеОперации.ВыполнитьВФоне() проверяет режим отладки. И если он включен - тупо выполняет задачу в основном потоке (чтоб тебе удобнее отлаживать). Поэтому все сообщения прилетают штатно.
24 Nicole
 
07.05.20
17:12
(20) (21) Попробую, спасибо.