![]() |
|
УФ как сделать прогресс-бар | ☑ | ||
---|---|---|---|---|
0
Никулин Леонид
14.12.15
✎
12:52
|
Здравствуйте!
Есть обработка, которая может выполняться несколько часов. Попросили добавить на форму ПолеИндикатора (прогресс бар) для визуального отображения сколько уже сделано и вообще не повисла ли программа. УФ. Код обработки выполняется в модуле формы. Компиляция &НаСервере. Если делать то же самое на клиенте индикатор плавно ползет "в реальном времени". Все ок. А у меня получается так.Запускаешь обработку. 0 процентов выполнено. Зависон на время цикла. 100 выполнено. Вопрос. Умные и талантливые, скажите можно ли добиться "плавности хода))" Возможно я не то что-то делаю Ниже добавлю код в отдельном сообщении для читаемости Спасибо! |
|||
1
Никулин Леонид
14.12.15
✎
12:54
|
&НаКлиенте
Процедура Погнали(Команда) // На клиенте все хорошо //ТекущееЗначение = 0; //Для Итератор = 1 По ВсегоЭлементов Цикл // // ПроцентВыполнения = Цел(Итератор * 100 / ВсегоЭлементов); // Если ПроцентВыполнения <> ТекущееЗначение Тогда // Объект.ИндикаторСостояния = ПроцентВыполнения; // Объект.СтрокаСостояния = ПроцентВыполнения; // // ОбновитьОтображениеДанных(); // ТекущееЗначение = ПроцентВыполнения; // КонецЕсли; //КонецЦикла; ПередачаДанныхССервера(); КонецПроцедуры &НаСервере Процедура ПередачаДанныхССервера() ТекущееЗначение = 0; Для Итератор = 1 По ВсегоЭлементов Цикл ПроцентВыполнения = Цел(Итератор * 100 / ВсегоЭлементов); Если ПроцентВыполнения <> ТекущееЗначение Тогда ОбработкаОбъект = РеквизитФормыВЗначение("Объект"); ОбработкаОбъект.ИндикаторСостояния = ПроцентВыполнения; ОбработкаОбъект.СтрокаСостояния = ПроцентВыполнения; ЗначениеВРеквизитФормы(ОбработкаОбъект, "Объект"); ТекущееЗначение = ПроцентВыполнения; КонецЕсли; КонецЦикла; КонецПроцедуры |
|||
2
los_hooliganos
14.12.15
✎
12:55
|
Сделай обработчик ожидания на клиенте.
Тока запись делай во внешний объект, а не в форму/отчет. |
|||
3
ДенисЧ
14.12.15
✎
12:55
|
Нельзя.
|
|||
4
Никулин Леонид
14.12.15
✎
12:55
|
((
|
|||
5
los_hooliganos
14.12.15
✎
12:57
|
(4) Пусть лучше с сервера шлет на сайт какой-нить. На сайт зашел и глянул скока сделано
|
|||
6
Никулин Леонид
14.12.15
✎
13:02
|
(2) я об этом думал, но у меня все на сервере. С клиента не получается. У меня цикл на сервере. Можно конечно еще один на клиенте конечно сделать, но это уже будет грубо.
(3) спасибо за комментарий (4) овчинка выделки не стоит Всем спасибо! |
|||
7
Fragster
гуру
14.12.15
✎
13:03
|
можно каждые хх итераций на сервере сохранять прогресс во временное хранилище, возвращаться на клиента, обновлять индикатор, и уходить обратно на сервер. типа так:
Адрес = СохранитьДанныеДляОбработки(Данные); Пока ИтерацияОбработки(Адрес) Цикл КонецЦикла; Данные = ПолучитьОбрабтанныеДанные(Адрес); СохранитьДанныеДляОбработки и ИтерацияОбработки - НаСервереБезКонтекста, в итерации данные достаются из хранилища, обрабатывается часть - и кладутся обратно. Если все обработано - возврат Ложь, Иначе - Возврат Истина. |
|||
8
los_hooliganos
14.12.15
✎
13:05
|
(7) Это бред. Не нужно так делать.
|
|||
9
los_hooliganos
14.12.15
✎
13:07
|
(6) Перед стартом на сервер запускай обработку, которая регулярно с регистра сведений будет читать состояние цикла.
|
|||
10
Никулин Леонид
14.12.15
✎
13:08
|
(7) Спасибо. Обязательно попробую.
(8) это может негативно сказаться на производительности? |
|||
11
Fragster
гуру
14.12.15
✎
13:10
|
(8) так можно делать. естественно, "итерация" - достаточно укрупненная.
В идеале, конечно, фоновым заданием, обработкой ожидания и, например, получитьСообщенияПользователя, но это уже без изменения конфигурации нельзя сделать. |
|||
12
Fragster
гуру
14.12.15
✎
13:11
|
а вот (9) - уже не надо, для получения из фоновой обработки данных прекрасно можно использовать сообщения пользователю и ХХХвременноехранилище
|
|||
13
los_hooliganos
14.12.15
✎
13:13
|
(11) Нельзя послать сообщение без изменения конфы??!
А гонять реквизиты высоконагруженной формы можно? |
|||
14
Fragster
гуру
14.12.15
✎
13:13
|
для (7) - переход на сервер без контекста - занимает примерно 0.01 секунды, работа со временным хранилищем - в зависимости от объема. соответственно, если мы будем обрабатывать данные в 100 раз дольше, чем (работа со врем. хранилищем + 0.01с), то оверхэд будет 1% на обновление счетчика
|
|||
15
Fragster
гуру
14.12.15
✎
13:14
|
(13)при использовании НаСервереБезКонтекста - ничего не гоняется
|
|||
16
Fragster
гуру
14.12.15
✎
13:15
|
(13) нельзя запустить фоновое задание с нужным кодом без изменения конфы, например из внешней обработки
|
|||
17
los_hooliganos
14.12.15
✎
13:17
|
(16) Суть в том что нам надо поднять даже не обработчик ожидания а сокет, который будет просто сидеть и ждать сообщений. Это идеально для клиент-сервера и в 8.3.7 это уже возможно.
|
|||
18
oslokot
14.12.15
✎
13:17
|
(16) а из внешней - фоново запустить другую внешнюю? прокатит?
|
|||
19
los_hooliganos
14.12.15
✎
13:19
|
(18) Строго говоря нет. Ибо фоновые/регламентные задания нужно заранее делать в самой конфе.
|
|||
20
Fragster
гуру
14.12.15
✎
13:21
|
(18) в теории подсистема ДлительныеОперации из БСП такое позволяет делать, но я не пробовал
|
|||
21
Fragster
гуру
14.12.15
✎
13:22
|
(17) зачем так много умных слов?
|
|||
22
Сергиус
14.12.15
✎
13:36
|
(0)Самый оптимальный вариант, как было сказано в (8). А что мешает изменить конфу, добавив один общий модуль, где и будет функция для фоновой загрузки?
|
|||
23
DexterMorgan
14.12.15
✎
13:44
|
(20) Позволяет, я пробовал и делал, но есть нюанс. По фэншую нужно посылать из фонового на клиент данные о состоянии индикатора через СообщениеПользователю, а принимать используя ФоновоеЗадание.ПолучитьСообщенияПользователю
В БСП фоновое задание в ДлительныхОперациях запускается без ключа, соответственно идентифицировать однозначно запущенное фоновое задание нельзя. Я помещал данные о состоянии индикатора в ХранилищеОбщихНастроек. |
|||
24
DexterMorgan
14.12.15
✎
13:45
|
(7) А ты плохое советуешь
|
|||
25
Fragster
гуру
14.12.15
✎
13:47
|
(24) это не всегда плохо, см (14)
|
|||
26
vhl
14.12.15
✎
13:47
|
БСП. ДлительныеОперации
|
|||
27
Fragster
гуру
14.12.15
✎
13:50
|
(23) судя по справке - есть параметр для этих целей, достаточно в обработчике ожидания брать оттуда прогресс, например.
// ИспользоватьДополнительноеВременноеХранилище – Булево – признак использования // дополнительного временного хранилища для передачи данных // в родительский сеанс из фонового задания. По умолчанию – Ложь. |
|||
28
DexterMorgan
14.12.15
✎
13:51
|
(27) Эти все временные хранилища доступны только после завершения фонового задания.
|
|||
29
Fragster
гуру
14.12.15
✎
13:52
|
(28) судя по справке - нет :)
|
|||
30
DexterMorgan
14.12.15
✎
13:56
|
(29) Из СП:
Примечание: Временное хранилище, сформированное в одном сеансе, недоступно из другого сеанса. Исключением является возможность передачи данных из фонового задания в сеанс, инициировавший фоновое задание, с помощью временного хранилища. Для такой передачи следует в родительском сеансе поместить во временное хранилище пустое значение, передав идентификатор формы. Затем полученный адрес передать в фоновое задание через параметры фонового задания. Далее, если этот адрес использовать в параметре <Адрес>, то результат будет скопирован в сеанс, из которого было запущено фоновое задание. Данные, помещенные во временное хранилище в фоновом задании, не будут доступны из родительского сеанса до момента завершения фонового задания. |
|||
31
DexterMorgan
14.12.15
✎
13:59
|
(29) Так данные будут переданы в родительский сеанс все правильно, только после завершения задания
|
|||
32
vhl
14.12.15
✎
14:14
|
(23) Все там есть.
&НаКлиенте Процедура ДлительныеОперации_Старт_Клиент() ОтключитьОбработчикОжидания("ДлительныеОперации_Обработчик"); РезультатЗапуска = ДлительныеОперации_Старт_Сервер(); ИдентификаторЗадания = РезультатЗапуска.ИдентификаторЗадания; АдресХранилища = РезультатЗапуска.АдресХранилища; Если РезультатЗапуска.ЗаданиеВыполнено Тогда ДлительныеОперации_Завершение(); Иначе ПодключитьОбработчикОжидания("ДлительныеОперации_ОбработчикОжидания", 1, Истина); КонецЕсли; КонецПроцедуры &НаСервере Функция ДлительныеОперации_Старт_Сервер() ПараметрыМетода = Новый Структура; ПараметрыМетода.Вставить("ПолноеИмяОбъекта", "Отчет.мойКрутойОтче"); ПараметрыМетода.Вставить("ДатаНач",ДатаНач); ПараметрыМетода.Вставить("ДатаКон",ДатаКон); ПараметрыМетода.Вставить("Контрагент",Контрагент); ПараметрыМетода.Вставить("Организация",ОрганизацияПТ); Возврат ДлительныеОперации.ЗапуститьВыполнениеВФоне( УникальныйИдентификатор, "ДлительныеОперации.ВыполнитьКомандуОтчетаИлиОбработки", ПараметрыМетода); КонецФункции &НаКлиенте Процедура ДлительныеОперации_ОбработчикОжидания() Попытка Если ЗаданиеВыполнено(ИдентификаторЗадания) = Истина Тогда ДлительныеОперации_Завершение(); Иначе Прогресс = ПрочитатьПрогресс(ИдентификаторЗадания); Если Прогресс <> Неопределено Тогда ПроцентВыполнения = Прогресс.Процент; ОтображениеСостояния.Текст = "Вполнение: "+ПроцентВыполнения+"%"; КонецЕсли; ПодключитьОбработчикОжидания("ДлительныеОперации_ОбработчикОжидания", 1, Истина); КонецЕсли; Исключение ДлительныеОперации_Завершение(Истина, ОписаниеОшибки()); Возврат; КонецПопытки; КонецПроцедуры &НаКлиенте Процедура ДлительныеОперации_Завершение(флЕстьОшибки = Ложь, вхТекстОшибки = "") Результат = ПолучитьИзВременногоХранилища(АдресХранилища); КонецПроцедуры В модуле отчета: Процедура ВыполнитьКоманду(ПараметрыВыполнения, АдресРезультата) Экспорт Договоры = ПараметрыВыполнения.Договоры; ДатаНач = ПараметрыВыполнения.ДатаНач; ДатаКон = ПараметрыВыполнения.ДатаКон; Контрагент = ПараметрыВыполнения.Контрагент; Организация = ПараметрыВыполнения.Организация; Результат = СкомпоноватьОтчет(ДатаНач, ДатаКон, Контрагент, Организация); Возврат ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецПроцедуры |
|||
33
DexterMorgan
14.12.15
✎
14:20
|
(32) Блин, вот ты делал? Понятно, что не делал, разуй свои глаза и перечитай (30), для тебя выделю:
"Данные, помещенные во временное хранилище в фоновом задании, не будут доступны из родительского сеанса до момента завершения фонового задания." Не будут доступны понимаешь? |
|||
34
Жан Пердежон
14.12.15
✎
14:29
|
запускаешь задание
ФоновыеЗадания.Выполнить("ДополнительныеОтчетыИОбработки.ВыполнитьКоманду", Параметры, Ключ, "Наименование"); где-то в коде задания ДлительныеОперации.СообщитьПрогресс(100, ТекстСообщения); в обработчике ожидания ДлительныеОперации.ПрочитатьПрогресс(ИдентификаторЗадания); |
|||
35
Fragster
гуру
14.12.15
✎
14:29
|
короче, в БСП нужно допилить - для возврата УИДа задания (ну, это просто). В самой форме в параметрах при создании на сервере будет ссылка на внешнюю обработку в ДополнительнаяОбработкаСсылка. через код, скопипащенный из формы выбора внешних обработок можно все запустить как надо
Попытка Если ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда Результат.Значение = ДополнительныеОтчетыИОбработки.ВыполнитьКоманду(ПараметрыВызоваСервера, Неопределено); Результат.Выполнено = Истина; Иначе РезультатФоновогоЗадания = ДлительныеОперации.ЗапуститьВыполнениеВФоне( УникальныйИдентификатор, "ДополнительныеОтчетыИОбработки.ВыполнитьКоманду", ПараметрыВызоваСервера, НСтр("ru = 'Дополнительные отчеты и обработки: Выполнение серверного метода обработки'")); Если РезультатФоновогоЗадания.ЗаданиеВыполнено Тогда Результат.Выполнено = Истина; Результат.Значение = ПолучитьИзВременногоХранилища(РезультатФоновогоЗадания.АдресХранилища); Иначе ФоновоеЗаданиеИдентификатор = РезультатФоновогоЗадания.ИдентификаторЗадания; ФоновоеЗаданиеАдресХранилища = РезультатФоновогоЗадания.АдресХранилища; КонецЕсли; КонецЕсли; Исключение Результат.ВызваноИсключение = Истина; ДополнительныеОтчетыИОбработки.ЗаписатьОшибку( ПараметрыВызоваСервера.ДополнительнаяОбработкаСсылка, НСтр("ru = 'Команда %1: Ошибка выполнения:%2'"), ПараметрыВызоваСервера.ИдентификаторКоманды, Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); КонецПопытки; |
|||
36
DexterMorgan
14.12.15
✎
14:32
|
(35) Ну вопрос как без допила, а чем ХранилищеОбщихНастроек плохо?
|
|||
37
Fragster
гуру
14.12.15
✎
14:32
|
даже допиливать ничего не надо, ИД задания в ДлительныеОперации.ЗапуститьВыполнениеВФоне(...).ИдентификаторЗадания
|
|||
38
Fragster
гуру
14.12.15
✎
14:32
|
(36) тем, что никто его не чистит
|
|||
39
DexterMorgan
14.12.15
✎
14:34
|
(38) ну надо чистить перед запуском, все дела
|
|||
40
DexterMorgan
14.12.15
✎
14:37
|
(37) Ох ты точно, да не вот это я не видел.
смоттрел что тут Задание = ФоновыеЗадания.Выполнить("РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации", ПараметрыЗадания,, НаименованиеЗадания); ключа нет и не смотрел что функция выполняет, тогда конечно |
|||
41
DexterMorgan
14.12.15
✎
14:37
|
(40) что функция возвращает*
|
|||
42
DexterMorgan
14.12.15
✎
14:38
|
(32) сорри, я думал ты мне про временное хранилище тоже пишешь
|
|||
43
Andreyyy
14.12.15
✎
14:38
|
||||
44
Никулин Леонид
14.12.15
✎
14:39
|
А можно еще раз для тех кто в танке. Так как все таки попробовать?
|
|||
45
Никулин Леонид
14.12.15
✎
14:43
|
(43) Ого. А я не знал что на Мисте есть такая штука. Каталог прям как на вражеском сайте. Буду курить. Там кажись понятно...
|
|||
46
DexterMorgan
14.12.15
✎
14:43
|
(45) это инфостарт, а не миста =)
|
|||
47
vhl
14.12.15
✎
14:46
|
(33) это рабочий код из рабочей базы. Можешь продолжать городить огороды с хранилищами настроек
|
|||
48
Никулин Леонид
14.12.15
✎
14:46
|
Вот черт! А шапка Мисты. Кругом обман! Я уж думал на Мисте тоже самое организовали
|
|||
49
DexterMorgan
14.12.15
✎
14:47
|
(47) ну извинился же в (42), был неправ
|
|||
50
Никулин Леонид
14.12.15
✎
15:11
|
https://yadi.sk/d/eGdJFRAC0KYZO то что доктор прописал. Достал из поста 43.
Всем большое спасибо! |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |