При обработке данных мне необходимо программно делать паузы через определенное количество обработанных данных на определенное количество секунд.
Пришло в голову два варианта:
Вариант 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);
КонецЕсли;
ОбработкаОжидания(<?>,)
Синтаксис:
ОбработкаОжидания(<ИмяПроцедуры>,<ИнтервалВызова>)
Назначение:
Инициирует периодический вызов процедуры глобального модуля с заданным интервалом времени.
Возвращает имя процедуры глобального модуля, которая назначена для периодического запуска (на момент до исполнения процедуры).
Параметры:
<ИмяПроцедуры> - необязательный параметр. Строковое выражение - имя процедуры глобального модуля, которая будет вызываться периодически с временным интервалом <ИнтервалВызова>. Тело процедуры <ИмяПроцедуры> должно быть написано разработчиком конфигурации в глобальном программном модуле. Если в качестве параметра передается 'пустая строка', то ранее запущенный процесс прекращается.
<ИнтервалВызова> - необязательный параметр. Числовое выражение - интервал времени в секундах, с которым периодически будет вызываться процедура глобального модуля <ИмяПроцедуры>. Если в качестве параметра передается 0 (ноль), то ранее запущенный процесс прекращается.
Ребят, зачем такие костыли делать? Есть простой способ используя встроенные методы, ничего не нагружает, не заметно для пользователя, работает как на дбф так и на скуле:
Процедура Пауза(Время) чЧас=0;чМин=0;чСек=0; ТекущееВремя(чЧас,чМин,чСек); чТекВремя =чЧас*3600+чМин*60+чСек; чВремяЗавершения=чТекВремя+Время; ПокачТекВремя<чВремяЗавершенияЦикл ТекущееВремя(чЧас,чМин,чСек); чТекВремя=чЧас*3600+чМин*60+чСек; КонецЦикла; КонецПроцедуры;
В переменную "время" передаете числовое значение секунды необходимое для паузы (60 - минута, 3600 = час - это садизм :))) ), работает с любыми числами, универсально
(13) В 7.7 как то не замечалось, что бы цикл не грузил процессор. В терминале подобные решения могут привести к проблемам с быстродействием базы в целом.
(13) madvovik, Предложенное Вами решение аналогично предложенному мною в самом начале первому варианту и грузит одно ядро процессора на 100 %. Вы проверяли предложенное решение?
ОбработкаОжидания(<?>,)
Синтаксис:
ОбработкаОжидания(<ИмяПроцедуры>,<ИнтервалВызова>)
Назначение:
Инициирует периодический вызов процедуры глобального модуля с заданным интервалом времени.
Возвращает имя процедуры глобального модуля, которая назначена для периодического запуска (на момент до исполнения процедуры).
Параметры:
<ИмяПроцедуры> - необязательный параметр. Строковое выражение - имя процедуры глобального модуля, которая будет вызываться периодически с временным интервалом <ИнтервалВызова>. Тело процедуры <ИмяПроцедуры> должно быть написано разработчиком конфигурации в глобальном программном модуле. Если в качестве параметра передается 'пустая строка', то ранее запущенный процесс прекращается.
<ИнтервалВызова> - необязательный параметр. Числовое выражение - интервал времени в секундах, с которым периодически будет вызываться процедура глобального модуля <ИмяПроцедуры>. Если в качестве параметра передается 0 (ноль), то ранее запущенный процесс прекращается.
Я думаю в в описании достаточно часто, указывается на ГМ?
"То что нет типовых механизмов, явно указывает на то что производится попытка "неправильного" использования программного продукта.
Судя по тексту
"
Предупреждение("Ожидание оправки пакета "+Цел(НомерСотрудника/20)+". Пожалуйста, не нажимайте кнопку ""ОК"".", 5);
"
видимо, Вы хотите производщить задержку при обмене данными.
Если это так, то ожидание, не "красивый" способ и не лучший с точки зрения реализации обмена.
Я бы переписал механизм обмена следующим образом:
1. С помощью плана обмена фиксировать изменения в необходимом типе объектов (по изменению которого вы понимаете что нужно обмениваться)
2. Реализовать регламентное задание:
2.1 Получаете все измененные объекты.
2.2 Осуществляете обмен.
2.3 Если обмен прошел успешно то удаляете изменения в плане обмена.
При такой реализации, обмен будет "невидим" для пользователей и обмен из за этого будет работать более стабильно. Расписание регламентного задания можно настроить хоть каждую секунду, но я бы рекомендовал посоветоваться с Заказчиком и сделать раз в 5 минут. Еще одним плюсом является то что регламентное зададание будет работать на сервере и не зависеть от работы клиентов."
Прошу прощения, не обратил внимание на то что эта тема по 7.7 и решение написал для 8.х, но возможно в 7.7 есть аналогичные механизмы.
А я и предлагаю паузу а не таймер
См код внимательней
В процедуре НачалоОбработки
начало обработки затем после заданной паузы -
однократное продолжение в процедуре ПродолжениеОбработки
(26) VLMedvedev,
Что-то мы друг друга недопонимаем :)
Хорошо, давай разберем ситуацию в деталях.
Допустим, есть некая длинная процедура обработки данных:
Процедура ОбработкаДанных()
...
// тут должна быть пауза на 10 секунд.
...
КонецПроцедуры // ОбработкаДанных()
В определенном месте этой процедуры мне необходимо вставить паузу на 10 секунд. Как будет выглядеть реализация с использованием ОбработкаОжидания()?
(27) zaursoft,
Помоему товарисч Pari ответил.
Можно на две процедуры одну разделить до и после паузы.
1С - язык процедурный !
А линейный код - это стиль индуских программистов.
zaursoft пишет:
В определенном месте этой процедуры мне необходимо вставить паузу на 10 секунд. Как будет выглядеть реализация с использованием ОбработкаОжидания()?
Процедура разбывается на две части. Первая часть запускается как обычно, заканчивается запуском обработки ожидания там, где нужно поставить паузу. Остальная часть кода пишется в виде второй процедуры, вызываемой из первой по обработке ожидания. Во второй процедуре обработка ожидания сбрасывается, т.е. вызов второй части происходит только один раз (после паузы), а не многократно. Само собой нужно чтобы переменные, используемые и в первой и во второй процедуре/части, были локальными переменными модуля формы, а не отдельных процедур.
Я обычно делаю все это с помощью обработчиков ожидания. Даже когда требуется две паузы (пауза в паузе, как аналог вложенных циклов) - можно всегда добавить глобальную переменную и проверять ее значение в обработчике ожидания, а потом в зависимости от условий выполнять тот или иной код. Получается все довольно красиво.
Тип: Число.
Время в секундах обработки очередной порции заданий. Если время не задано, будет выполнен только один цикл обработки.
Описание:
Вызывает обработку текущих заданий. Имеет смысл только для файлового варианта.
В управляемом режиме в толстом, тонком и веб-клиентах приводит к появлению диалога, содержащего сообщение о выполнении обработки заданий и кнопку "Прервать", нажатие на которую приводит к прерыванию цикла обработки заданий.
Для 1с 8.2 и не только) Перелопатил всё, задержка нужна была именно в 0,1с (100мс), а, например Предупреждение меньше 1 секунды не хавает. Помог только пример с сайта http://extremallife.ru:
В данном случае выполняется стандартная для всех версий Windows команда ping на IP-адрес, ответа от которого не будет и выставляется время ожидания отклика в секундах.
В данном примере задержка составляет 5 секунд, сама команда ping использует время в миллисекундах.
(42) Maxx2008, На компе как минимум может быть "не поднят" сетевой интерфейс плюс функция Формат может повести себя непредсказуемо и отработка её может занять, скажем так "какое-то время"... Скриптовый Sleep в таких ситуациях на порядок "надёжнее"...
(46) Serginio, но код-то Вы в теме запостили "восьмёрошный"... Понятно Ваше желание "прорекламировать" статью, но, ИМХО, "пилить" сборку ради паузы... да еще с "нюансами" на 7.7....
Не надо пилить сборку. Ты можешь использовать все, что находится в GAC.
Уже подключены
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" /
Но ты можешь всегда достучаться из до GAC через AssemblyQualifiedName
например
(51) Serginio, Конечно, нет) Я про то и намекаю, что ради паузы, которая намного проще решается что-то еще докачивать, регистрировать, допиливать пилить и передопиливать и т.д... не та задача...
(53) Serginio, Типа "зачем тебе отвертка, покупай набор слесаря!!! Сегодня шуруп, завтра дюбель... а там глядишь и крышу крыть надо!" ИМХО не совсем здравый подход... благо та же пауза без Net решается еще элементарнее чем с ним...
Правда код не совсем верен. Проблема в том, что 1000 семерка интерпретирует как Double а в Net нужно прямое соответствие типов.
Поэтому введены функции конвертации
Функция Децимал(стр)
возврат врап.ToDecimal(Строка(стр));
КонецФункции // Децимал
Функция Инт(стр)
возврат врап.ToInt(Строка(стр));
КонецФункции // Децимал
Показать
И правильный код выглядит так
врап=СоздатьОбъект("NetObjectToIDispatch45");
врап.УстЭтоСемерка();
Thread=Врап.ПолучитьТип("System.Threading.Thread");
Thread.Sleep( врап.ToInt("1000"));
// или
Thread.Sleep( врап.ToInt(1000));