Как установить задержку в выполнении команд модуля (приостановить выполнение). Как сделать эту задержку разной продолжительности в зависимости от времени суток (1С: Программисту) — 1C-h
 

Как установить задержку в выполнении команд модуля (приостановить выполнение). Как сделать эту задержку разной продолжительности в зависимости от времени суток (1С: Программисту)

Иногда какая-то обработка может существенно тормозить работу пользователей, например, из-за ожидания освобождения от блокировок регистров. При этом могут скапливаться, например, фоновые задания. И в какой-то момент пользователи даже не смогут войти в базу.

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

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

Вот примерный текст модуля, решающий эту задачу.

    ТаблицаЗаполнения = Запрос.Выполнить().Выгрузить();
    Сообщить("2 Приступаем к обработке результата запроса к регистру """ +     ИмяРегистраСведений + """ - " + ТекущаяДата());
    МаксимальноеЗначениеИндикатора = ТаблицаЗаполнения.Количество();

    // заполнение строки progress bar
    ЭлементыФормы.Индикатор2.Значение = 0; // обнуляем, чтобы при повторном запуске статусбар сбросился в 0
    ЭлементыФормы.Индикатор2.МаксимальноеЗначение =     МаксимальноеЗначениеИндикатора; // задаем значение для 100%

    Старт = ТекущаяДата();
    ОчереднойСтарт = Старт;

    // переменные для организации прерывания(задержки)
    // ПроцентеВыполненния - это реквизит формы (доступный пользователю для редактирования), в котором хранится размер "порции", по порохождению которой нужно приостановить выполнение
    ШагПрерывания = 1;
    ЧислоПрерывания = МаксимальноеЗначениеИндикатора * ПроцентеВыполненния / 100;

    ШестьУтраТекущегоДня = (Дата(Год(ТекущаяДата()), Месяц(ТекущаяДата()), День(ТекущаяДата())) + 21600);
    ОдиннадцВечераТекДня = (Дата(Год(ТекущаяДата()), Месяц(ТекущаяДата()), День(ТекущаяДата())) + 82800);
    ШестьУтраСледующгДня = (Дата(Год(ТекущаяДата()), Месяц(ТекущаяДата()), День(ТекущаяДата())) + 108000);

    // для каждой строки таблицы значений установим отбор и перезапишем регистр
    Для Каждого СтрокаЗаполнения Из ТаблицаЗаполнения Цикл

        ТекущийПН = ЭлементыФормы.Индикатор2.Значение + 1; // - текущий порядковый номер обрабатываемой строки таблицы
        ЭлементыФормы.Индикатор2.Значение = ТекущийПН; // - указываем прирост внутри цикла для ползущего индикатора выполнения обработки

        // посчитаем, сколько времени затрачено и прикинем сколько времени осталось
        // для вывода на морду формы: уже затрачено времени:
        ЗатраченоВремени = ТекущаяДата() - Старт;
        // для вывода на морду формы: затрачено времени на обработку одной строки таблицы:
        ВремениНаЕдиницу = Окр(ЗатраченоВремени / ТекущийПН,8);
        // для вывода на морду формы: времени на выполнение еще требуется:
        ОсталосьВремени = Окр((МаксимальноеЗначениеИндикатора - ТекущийПН)*ВремениНаЕдиницу/60);

        Если ПрерватьНаПроцентахВыполнения И ТекущийПН > ЧислоПрерывания Тогда // ПрерватьНаПроцентахВыполнения - булево, галочка в форме о необходимости задержки выполнения
                // в дневное время цикл задержки:
                Если ТекущаяДата() > ШестьУтраТекущегоДня И ТекущаяДата() < ОдиннадцВечераТекДня Тогда // это день
                        // сделаем паузу, чтобы рассосались блокировки
                        // в этом цикле мы умножаем количество заданных секунд задержки для дня (СекундЗадержкиДнем) на номер шага прерывания, тем самым определяя, очередную порцию задержки относительно Текущего Времени
                        Пока (ТекущаяДата() - Старт) < СекундЗадержкиДнем * ШагПрерывания Цикл
                        КонецЦикла;

                // ночное время:
                ИначеЕсли ТекущаяДата() > ОдиннадцВечераТекДня И ТекущаяДата() < ШестьУтраСледующгДня Тогда
                        // сделаем паузу, чтобы рассосались блокировки
                        // в этом цикле мы умножаем количество заданных секунд задержки для ночи (СекундЗадержкиНочью) на номер шага прерывания, тем самым определяя, очередную порцию задержки относительно Текущего Времени
                        Пока (ТекущаяДата() - Старт) < СекундЗадержкиНочью * ШагПрерывания Цикл
                        КонецЦикла;

                КонецЕсли;
                //следующее число прерывания и очередной шаг прывания:
                ШагПрерывания = ШагПрерывания + 1;
                ЧислоПрерывания = МаксимальноеЗначениеИндикатора * ПроцентеВыполненния * ШагПрерывания / 100;

        КонецЕсли;
        // далее в идет та часть кода обработки очередной порции данных, которую мы собственно хотели выполнять порциями
        // ...

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Next Post

Как заменить значение измерения регистра сведений и при этом не потерять числовые ресурсы. Универсальная процедура массовой замены значения измерения регистра сведений (1С: Программисту: Регистры сведений)

Чт Апр 14 , 2011
В том случае, когда в каком-то регистре сведений нужно заменить несколько видов значений какого-то конкретного измерения на заданное значение, при простой попытке замены с помощью метода СоздатьНаборЗаписей(), возможно возникновение ситуации попытки записи неуникального набора измерений. При этом могут потеряться числовые значения ресурсов регистра. Код 1С, универсально решающий такую задачу: