1с имитировать задержку при вызовах сервера что это

Обновлено: 03.07.2024

При обработке данных мне необходимо программно делать паузы через определенное количество обработанных данных на определенное количество секунд.
Пришло в голову два варианта:
Вариант 1. Используем _getPerformanceCounter():
Для НомерСотрудника = 1 По КолвоСотрудников Цикл
Если (НомерСотрудника>1) И (НомерСотрудника%20 = 1) Тогда
СчетчикВремени1 = _getPerformanceCounter();
Пока 1=1 Цикл
СчетчикВремени2 = _getPerformanceCounter();
ПаузаСекунд = (СчетчикВремени2-СчетчикВремени1)/1000;
Если ПаузаСекунд > 5 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;

Вариант 2. Используем Предупреждение():
Для НомерСотрудника = 1 По КолвоСотрудников Цикл
Если (НомерСотрудника>1) И (НомерСотрудника%20 = 1) Тогда
Предупреждение("Ожидание оправки пакета "+Цел(НомерСотрудника/20)+". Пожалуйста, не нажимайте кнопку ""ОК"".", 5);
КонецЦикла;

Плюсы: Не нагружает процессор.
Минусы: на каждое предупреждение отображается табличка и пикает сигнал спикера.

Вопрос: Есть ли вариант решения, при котором не нагружался бы процессор, и не отображались окна, и не пикал спикер?

Есть внешняя компонента (кажется, здесь где-то видел), называется TerminalSleep. Она как раз и делает системный вызов sleep(кол-во миллисекунд) не нагружая процессор.

(10)
Addin Romix'а делает паузу на указанное число мс
Если ЗагрузитьВнешнююКомпоненту(КаталогИБ()+"vk_sleep_1C.dll")=1 Тогда
vk_sleep=СоздатьОбъект("Addin.vk_sleep_1C");
vk_sleep.sleep(5000);
КонецЕсли; (1) можно запустить командную строку с паузой и подождать ее выполнения. (1) если все это выглядит сложно, то просто делайте цикл с бесполезными действиями, так раньше делали разного рода специалисты из франчайзинга. (36) ture, цикл с бесполезными действиями грузит ядро на 100%, а условие ТС - "грузить не должно". (37) ну тогда открыть предупреждение с указанием секунд.

scr = СоздатьОбъект("WScript.Shell");
scr.Run("ping 127.0.0.1 -n "+СокрЛП(Число(ЗадержкаСекунд)),0,1);

Не нагружает процессор и не пикает спикером.

Скрипт=Новый ТекстовыйДокумент();
Скрипт.УстановитьТекст
(
"if (WScript.Arguments.Count()==0)
| WScript.Quit();
|else
| if (isNaN(parseInt(WScript.Arguments(0))))
| WScript.Quit();
|WScript.Sleep(WScript.Arguments(0));"
);
Скрипт.Записать(КаталогВременныхФайлов()+"sleep.js",КодировкаТекста.ANSI);
WshShell=Новый COMОбъект("wscript.shell");
Сообщить(ТекущаяДата());
WshShell.Run("wscript.exe """+КаталогВременныхФайлов()+"sleep.js"" "+Формат(ИнтервалОжидания,"ЧГ=0"),0,-1);
Сообщить(ТекущаяДата());
УдалитьФайлы(КаталогВременныхФайлов()+"sleep.js");

scr = СоздатьОбъект("WScript.Shell");
scr.Run("ping 127.0.0.1 -n "+СокрЛП(Число(ЗадержкаСекунд)),0,1);

Не нагружает процессор и не пикает спикером.

Shell = Новый COMОбъект("WScript.Shell");
Shell.Run("ping 127.0.0.1 -n 2",0,1);

Есть еще в семерке стандартный вариант:

ОбработкаОжидания(<?>,)
Синтаксис:
ОбработкаОжидания(<ИмяПроцедуры>,<ИнтервалВызова>)
Назначение:
Инициирует периодический вызов процедуры глобального модуля с заданным интервалом времени.
Возвращает имя процедуры глобального модуля, которая назначена для периодического запуска (на момент до исполнения процедуры).
Параметры:
<ИмяПроцедуры> - необязательный параметр. Строковое выражение - имя процедуры глобального модуля, которая будет вызываться периодически с временным интервалом <ИнтервалВызова>. Тело процедуры <ИмяПроцедуры> должно быть написано разработчиком конфигурации в глобальном программном модуле. Если в качестве параметра передается 'пустая строка', то ранее запущенный процесс прекращается.
<ИнтервалВызова> - необязательный параметр. Числовое выражение - интервал времени в секундах, с которым периодически будет вызываться процедура глобального модуля <ИмяПроцедуры>. Если в качестве параметра передается 0 (ноль), то ранее запущенный процесс прекращается.

(6) ArCtic,
Это немножко не то. Используя функцию ОбработкаОжидания() можно сделать таймер, а мне нужна была пауза при исполнении кода. scr = СоздатьОбъект("WScript.Shell");
scr.Run("sleep "+СокрЛП(Число(Сек)),0,1); onyx пишет:
scr = СоздатьОбъект("WScript.Shell");
scr.Run("sleep "+СокрЛП(Число(Сек)),0,1);
Не работает в 7-ке. Пишет ошибку:
scr.Run("sleep "+СокрЛП(Число(Сек)),0,1);
: :

Ребят, зачем такие костыли делать? Есть простой способ используя встроенные методы, ничего не нагружает, не заметно для пользователя, работает как на дбф так и на скуле:
Процедура Пауза ( Время )
чЧас = 0 ; чМин = 0 ; чСек = 0 ;
ТекущееВремя( чЧас , чМин , чСек );
чТекВремя = чЧас * 3600 + чМин * 60 + чСек ;
чВремяЗавершения = чТекВремя + Время ;
Пока чТекВремя < чВремяЗавершения Цикл
ТекущееВремя( чЧас , чМин , чСек );
чТекВремя = чЧас * 3600 + чМин * 60+ чСек ;
КонецЦикла;
КонецПроцедуры;

В переменную "время" передаете числовое значение секунды необходимое для паузы (60 - минута, 3600 = час - это садизм :))) ), работает с любыми числами, универсально

(13) В 7.7 как то не замечалось, что бы цикл не грузил процессор. В терминале подобные решения могут привести к проблемам с быстродействием базы в целом. (13) madvovik, Предложенное Вами решение аналогично предложенному мною в самом начале первому варианту и грузит одно ядро процессора на 100 %. Вы проверяли предложенное решение?

Процедура ПродолжениеОбработки
ОбработкаОжидания("ПродолжениеОбработки",0);
//Продолжаем обработку
А=В;

Процедура НачалоОбработки
В=С;
//Тут начало
//Запускаем паузу
ПаузаСек=3;
ОбработкаОжидания("ПродолжениеОбработки",ПаузаСек);

Единственная проблема с модальностью форм обработка ожидания при модальных формах и не модальных рвботает по разному (честно не помню как)

(17) VLMedvedev, Это уже предлагали в (6), я ответил в (7). Пожалуйста, читайте ветку перед ответом. ну она работает только в ГЛ, а запустить ее из модуля обработки к примеру, будет работать?

процедура ТвояПроц - в этой же обработке, а не в ГМ

ОбработкаОжидания(<?>,)
Синтаксис:
ОбработкаОжидания(<ИмяПроцедуры>,<ИнтервалВызова>)
Назначение:
Инициирует периодический вызов процедуры глобального модуля с заданным интервалом времени.
Возвращает имя процедуры глобального модуля , которая назначена для периодического запуска (на момент до исполнения процедуры).
Параметры:
<ИмяПроцедуры> - необязательный параметр. Строковое выражение - имя процедуры глобального модуля , которая будет вызываться периодически с временным интервалом <ИнтервалВызова>. Тело процедуры <ИмяПроцедуры> должно быть написано разработчиком конфигурации в глобальном программном модуле . Если в качестве параметра передается 'пустая строка', то ранее запущенный процесс прекращается.
<ИнтервалВызова> - необязательный параметр. Числовое выражение - интервал времени в секундах, с которым периодически будет вызываться процедура глобального модуля <ИмяПроцедуры>. Если в качестве параметра передается 0 (ноль), то ранее запущенный процесс прекращается.

Я думаю в в описании достаточно часто, указывается на ГМ?

(20)
в (19) - недокументированная возможность
ОбработкуОжидания() можно использовать с локальной процедурой

"То что нет типовых механизмов, явно указывает на то что производится попытка "неправильного" использования программного продукта.

Судя по тексту
"
Предупреждение("Ожидание оправки пакета "+Цел(НомерСотрудника/20)+". Пожалуйста, не нажимайте кнопку ""ОК"".", 5);
"
видимо, Вы хотите производщить задержку при обмене данными.
Если это так, то ожидание, не "красивый" способ и не лучший с точки зрения реализации обмена.
Я бы переписал механизм обмена следующим образом:
1. С помощью плана обмена фиксировать изменения в необходимом типе объектов (по изменению которого вы понимаете что нужно обмениваться)
2. Реализовать регламентное задание:
2.1 Получаете все измененные объекты.
2.2 Осуществляете обмен.
2.3 Если обмен прошел успешно то удаляете изменения в плане обмена.

При такой реализации, обмен будет "невидим" для пользователей и обмен из за этого будет работать более стабильно. Расписание регламентного задания можно настроить хоть каждую секунду, но я бы рекомендовал посоветоваться с Заказчиком и сделать раз в 5 минут. Еще одним плюсом является то что регламентное зададание будет работать на сервере и не зависеть от работы клиентов."

Прошу прощения, не обратил внимание на то что эта тема по 7.7 и решение написал для 8.х, но возможно в 7.7 есть аналогичные механизмы.

Более подробно про проверенные варианты:

1) ping и winmgmts. Оба варианта прекрасно работают, практически не нагружая процессор.

2) Пустой цикл. Вариант работающий, часто предлагаемый на форумах. Имеет большой минус - грузит процессор.

3) Вариант с использованием Sleep. Насколько я понимаю, требуют наличия программы sleep.exe. На моем компьютере такой нет, варианты проверить не удалось.

4) SleepJs и SleepVbs. Работают. Неплохой вариант. Варианты отличаются только алгоритмом запуска команды.

5) TimeoutWs и Timeout. Работают. Неплохой вариант. Варианты отличаются только алгоритмом запуска команды. Timeout показывает черное окно при каждом запуске паузы.

6) DynamicWrapper. Нужна dll. Этот вариант не проверял, так как искал вариант без внешних компонент.

В прилагаемой обработке все варианты можно протестировать в своей базе и выбрать наиболее подходящий.

Есть обычная и управляемая форма, поэтому запускать можно в любой базе. Код открыт.

Протестировано на версиях 8.2 и 8.3.11.

Специальные предложения

Electronic Software Distribution

Интеграция 1С с системой Меркурий

Алкогольная декларация

Готовые переносы данных

54-ФЗ

Управление проектом на Инфостарте

Траектория обучения 1С-разработчика

Странно, что не работает SleepVbs. Я обычно таким методом пользуюсь, на компах с Виндовс работает. (1) Сравнил с (7). Работает, у меня пауза была не в секундах, а в миллисекундах, поэтому я решил, что не работает.

Кроме очевидного - задержки, не нагружая системные ресурсы - этот метод даёт пользователю возможность прервать длительный процесс, а нам - корректно отработать это прерывание и сделать всё красиво.

Ах, да, и самое, наверное, важное: этот метод работает с любым клиентом в любой операционной системе. В отличие от.

user1334089; viktor3d; independ; Merkalov; hydro2588_2015; user1058740; SVSVSV999; adhocprog; seperblunt2; DarkUser; y.dyachenko; TreeDogNight; necropunk; jif; Yakud3a; Gluk_1C; mickey.1cx; vano-ekt; forseil; NeviD; WizaXxX; + 21 – Ответить

(4) +1, какой-то набор вредных советов в статье :) Если только нужно именно на сервере пауза, в очень редких случаях.

Найдено в недрах БСП:

Платформо-независимо, работает на сервере, не нагружает процессор.
Вызов из БСП:

fuser; Andrei_Ivanov; FuJluH; user1188623; Smallrat; Anosov_EP; wolder; sodrk; KirinaAS; Aleskey_K; Invodev; KostyaLavr; Merkalov; axsebur; serg1c; vita8383; beardlyhich; Mi4man; hydro2588_2015; KilloN; davdykin; user990914; Anything; batusai_00; Alex_Prodigy; aezdakov; QZet; json; dreamerr7; adhocprog; Vampeg; leonidt84; boogie; noon; uno-c; + 35 – Ответить

Найдено в недрах БСП:

Платформо-независимо, работает на сервере, не загружает процессор.
Вызов из БСП (пример):

user1525588; Irwin; suepifanov; beardlyhich; MrBukas; Anything; Емельянов Алексей; user774630; Alogy; Vampeg; + 10 – Ответить (45) Все верно, это старый метод, с 8.3.13 использовать надо "ОжидатьЗавершенияВыполнения" (5) Эти очень редкие случаи когда встречаются. То вредные советы очень нужны. (4)
То, что Вы предлагаете, принципиально не годится, именно из-за асинхронности. Нужна ПАУЗА! А у Вас не будет никакой паузы. Висящий вопрос в асинхронном режиме - это не пауза, т.к. программа уже пошла вовсю дальше работать. То, что Вы предлагаете, принципиально не годится, именно из-за асинхронности. Нужна ПАУЗА! А у Вас не будет никакой паузы. Висящий вопрос в асинхронном режиме - это не пауза, т.к. программа уже пошла вовсю дальше работать.

То есть, как делать формы для работы в асинхронном режиме, Вы не умеете. Но это - недостаток Вас как специалиста, а не моего ответа как алгоритма.

Подскажу для тех, кто в танке: код в методе ПриОткрытииЗавершение() выполнится только после завершения ожидания.
Переносите в него всё, что должно было отработать после паузы, и всё!

(17)
То есть, смысл моего замечания Вы не поняли. Но это - недостаток Вас как специалиста, а не моего замечания :).
Уж конечно, я понимаю, что "код в методе ПриОткрытииЗавершение() выполнится только после завершения ожидания". Но вот то, что ПОСЛЕ ПоказатьВопрос - выполнится сразу. И вот этот "гениальный" подход : "Переносите в него всё, что должно было отработать после паузы, и всё" - применим не всегда. Или для этого нужно извратиться так, как рвать гланды через Ж. Статья вообще не об этом, а о паузе. А это не ПАУЗА ( впрочем, что-то я повторяюсь, а зачем ? ) Статья не настолько полезна, насколько вредна.
Если нужна пауза в клиентском коде, то есть ПодключитьОбработчикОжидания() и не нужно изобретать велосипед.
Если нужна пауза в серверном коде, то что-то не так с логикой приложения. Если нужна пауза в серверном коде, то что-то не так с логикой приложения.
Вы считаете, что обработкам, выполняющимся на сервере, совсем никогда не нужна задержка выполнения?
Реальный пример кода, где обработка ждет, когда все задания отправятся на принтер. Кстати, применен один из методов паузы, описанный автором статьи:
3) Варианты с использованием Sleep. Насколько я понимаю, требуют наличия программы sleep.exe.

Не соглашусь с автором - вариант SleepJs прекрасно работает.

(7) Работает, у меня пауза была не в секундах, а в миллисекундах, поэтому я решил, что не работает.

Будет платформенонезависимо, будет работать на клиенте. Но опять-таки, не работает в безопасном режиме (хотя на сервере профиль безопасности можно настроить, чтобы работало - для КОРП лицензии сервера).

Если очень хочется ждать на сервере, то на мой взгляд наименее костыльный способ - это ожидание фоновым заданием самого себя.

json; adhocprog; uno-c; KEV_SZK; JohnyDeath; Evil Beaver; Krio2; Darklight; nixel; azubar; Labotamy; + 11 – Ответить

Ожидание на фоновом задании - самое интересное решение (сам только что хотел предложить такое же) - но, надо бы проверить как будет вести себя в файловой базе. Предложу ещё фичу - один раз запустить "бесконечное" регл. задание (аналогично ждущее завершения самого себя) - и всем остальным сеансам обращаться на ожидание завершения ФЗ этого регл. задания. Но будет одна пользовательская лицензия расходоваться на регл. задание. Но ФЗ доступны только на сервере или в толстом клиенте - но для длительного ожидания можно и в серверный контекст переходить - это не проблема.

Остальные все советы платформенозависимые (хотя некоторые подходы можно переработать так, чтобы они имели реализацию для разных платформ).
Использовать WshShell
WshShell = Новый COMОбъект("Wscript.Shell");
WshShell.Run("Wscript.exe. ")

Всё же не рекомендую - 10-я версия платформы на это может ругаться, да ещё и в безопасном режиме работать не будет.
Но если надо так - то лучше "ЗапуститьПриложение(КомандаWindows,,Истина);" - по крайней мере будет работать в Windows, Linux и MacOS (c WEB-клиентом могут быть проблемы), где теперь тоже есть клиенты 1С.

Если нужно чисто на клиенте - то придётся извращаться с "ПодключитьОбработчикОжидания" - если нужно платформеннонезависимое решение, работающее в безопасном режиме, без модальности.

Но прямо среди кода остановиться так не получится - но, на мой взгляд, если такой код разбить на части через "ПодключитьОбработчикОжидания" не получится - значит там явно очень плохой дизайн.

Либо, нужно просто написать классический бесконечный цикл (думаю, что сюда попадут лишь короткие паузы - не более пары секунд- можно и покрутить проц клиента - коли уж очень нужно).

Или писать платформеннозависимый не безопасный код через вызов «ЗапуститьПриложение» или, ожидать на фоновом задании (регламентном или специально запускаемом), ждущим самого себя; с заходом в серверный контекст выполнения (если это не толстый клиент).

В общем всё ещё ждём, когда 1С встроит в платформу системную функцию паузы. давно ждём.

Доп вопросы от преподавателя

1. Если мы собрали Profiler трассировку по запросам, то какие запросы смотреть?

Ответ: С большей длительностью. Можно отсортировать отчеты по Duration.

2. Как отследить кто сейчас выполняет длительные запросы с помощью консоли кластера 1С?

Ответ: Решается при помощи консоли сервера 1С Предприятия 8.3 (8.2). Смотрим текущее соединение, колонка «SPID занят». У пользователей, которые выполняют длительные запросы, время удержания соединения будет большим.

3. Как называется файл технологического журнала?

Ответ: logcfg.xml

Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>

4. Ситуация: есть информационная база. В ней пользователь проводит документ на управляемых формах. Занимает это 5 секунд. А по Профайлеру видно, что запрос выполняется 0.5 секунды. Куда ушло время и как это определить?

Ответ: Скорее всего, виной этому динамический список. Нужно в технологическом журнале собрать все события, которые связаны с вызовами.

5. Свойство транзакции Durabiliti что это такое?

Ответ: Одно из основных свойств транзакции (“надёжность”).

6. Уровень изоляции read commited snapshot 1С

Ответ: Поддержка read commited snapshot появилась в версии 8.3. Она позволяет увеличить параллельность работы системы благодаря использовании при чтении изменяемого объекта предыдущей версии объекта. Это заметно улучшает быстродействие системы, однако требует больших аппаратных ресурсов.

Тут стоит сказать о том, что мы избавляемся от грязного чтения вообще, так как читаем версию завершенных транзакций. А так же о том что на СУБД у нас читатель не блокирует писателя, а писатель читателя. Не путать с упр. блокировками.

7. Как вообще замерить время за которое выполняется операция.

8. Есть сервер 1С предприятия и сервер СУБД. Выполняется какая то операция и нужно выполнить кто виноват сервер 1С 8.2 или сервер СУБД. Почему тормозит и куда уходит время.

Ответ: Можно сделать замер в профайлере. Если Duration большое то проблема на стороне СУБД, если нет то на стороне 1С Сервера.

Ответ: При использовании данного свойства при записи набора движений будут автоматически наложены исключительные управляемые блокировки на все измерения данного регистра. Это позволяет избежать дедлока на сплиттере. Цитата с диска ИТС: “Необходимая управляемая блокировка будет автоматически установлена платформой в том случае, если записывается набор записей регистра, у которого данное свойство имеет значение Истина.”

10. События в SQL Profiler по которыми смотрим запросы и блокировки и что видим

Ответ:

11. Можно ли делать транзакцию на клиенте?

Ответ: Нет, транзакции могут быть созданы только на уровне сервера СУБД.

12. Стало больше пользователей в базе, операции стали медленнее. Почему?

13. Знаем ли мы какое-то время, через которое взаимоблокировка разрешится, типа таймаута в 20 секунд? Можно ли задавать такое время в SQL?

Ответ: По умолчанию в MS SQL Server это время 5 секунд, после нахождения первого дедлока система начинает проверять дедлоки раз в 100 мс.

14. Что в оборудовании может влиять на производительность и как это посмотреть?

Ответ: С помощью Perfomance Monitor.

  • Очередь к процессору (не более 2 к ярду процессора)
  • Очередь к жесткому диску (ПЗУ) (не более 2)

15. Как произвести расследование ожидания на блокировках?

Системная процедура sp_lock:

SPID блокирующего процесса

SPID заблокированного процесса

Время ожидания на блокировке

MS SQL Profiler. События Locks\Lock:Acquired по условию Duration >= 1 мс. Информация:

Какой запрос SQL заблокирован

Время ожидания на блокировке

Утилита администрирования клиент-серверного варианта. Информация:

Кто блокирует (Пользователь А)

Кого блокирует (Пользователь Б)

Сколько времени блокирует

Дождаться ошибки «time out». Информация: Только факт того, что пользователь Б был заблокирован при выполнении конкретной операции

Технологический журнал. Информация по событию «DB». Информация:

Кого заблокировали (с точностью до запроса SQL и строки кода)

Можно примерно определить, кто заблокировал (с точностью до нескольких запросов SQL)

16. Какие существуют атрибуты свойств Технологический журнала?

С появлением управляемых форм в модулях форм 1С 8.3 стали активно использоваться директивы компиляции в модулях форм и объектов:

Дальше речь пойдет о том, как правильно ими пользоваться и как с их помощью можно оптимизировать работу системы.

Архитектура управляемого приложения 1С 8


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

Обратите внимание! Если директива не указана, то по умолчанию она выполняется на сервере.

Особенности компиляции этих директив управляемого приложения

&НаКлиенте

На клиенте есть доступ к следующим объектам:

  • методы глобального контекста, у которых есть доступ на клиент (доступные директивы можно увидеть в синтаксис-помощнике); , которые скомпилированы на сервере;
  • локальный контекст модуля;
  • свойства и методы расширения формы, определяемого основным реквизитом;
  • свойства и методы объекта встроенного языка УправляемаяФорма;
  • реквизиты формы.

&НаСервере

Выполняется на сервере, переменные существуют только на время серверного вызова. С сервера допустим вызов практически любых процедур, кроме клиентских. Если работа происходит в режиме тонкого клиента, вся работа происходит на сервере, а клиент получает лишь результат выполнения.

&НаСервереБезКонтекста

Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>

Это процедура выполняется на сервере, вне контекста формы. Т.е. процедура не имеет доступа к реквизитам формы, выполняется на сервере и возвращает желаемый результат. Хорошо подходит для получения статичных данных. Крайне рекомендуется к использованию для оптимизации клиент-серверного взаимодействия.

&НаКлиентеНаСервереБезКонтекста

Используется, когда к процедуре нужно обращаться и с клиента, и с сервера. В остальном аналог &НаСервереБезКонтекста.

Оптимизация клиент-серверного взаимодействия

При разработке функционала необходимо учитывать следующие нехитрые правила:

  • в первую очередь минимизировать количество северных вызовов 1С с клиента;
  • производить все объемные вычисления на сервере;
  • там, где можно, использовать НаСервереБезКонтекста вместо НаСервере.

Читайте также: