7.7 Обработка Ожидания

Тема в разделе "1C и всё что с ней связано", создана пользователем olga13, 2 мар 2012.

  1. olga13

    olga13 Well-Known Member

    Регистрация:
    10 окт 2008
    Сообщения:
    208
    Симпатии:
    0
    Добрый день. Столкнулась с такой проблемой: необходимо с разным интервалом времени вызывать две процедуры из глобального модуля. Если разместить две ОбработкаОжидания(), выполняется только вторая. Как быть?
     
  2. Allexei

    Allexei Well-Known Member

    Регистрация:
    2 май 2008
    Сообщения:
    322
    Симпатии:
    0
    Как вариант написать батник вызывающий эти процедуры и через планировщик заданий запускать их.
     
  3. olga13

    olga13 Well-Known Member

    Регистрация:
    10 окт 2008
    Сообщения:
    208
    Симпатии:
    0
    Не совсем представляю, как из батника можно вызвать процедуру 1С B)
     
  4. Paume

    Paume Well-Known Member

    Регистрация:
    15 дек 2010
    Сообщения:
    110
    Симпатии:
    0
    Я на ОбработкуОжидания положила процедуру, в которой потом анализировала время и уже по нему смотрела, какую из процедур вызывать дальше.
     
  5. olga13

    olga13 Well-Known Member

    Регистрация:
    10 окт 2008
    Сообщения:
    208
    Симпатии:
    0
    Я думаю, такой вариант мне подойдет. Спасибо за совет.
     
  6. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    У меня таких процедур аж 7. И возникают задачи:
    - вызывать с разной частотой.
    - за один раз вызывать только одну процедуру.
    Иначе может упасть быстродействие вообще. А если пару процедур сработали одновременно, то "тормознет" на несколько сек.
    Мой Глобальный модуль:
    Код ( (Unknown Language)):
    Перем ТекВызов;                        // текущий счетчик вызовов
    Процедура Ожидание()

    //  При старте системы
    Если ПустоеЗначение(ТекВызов) = 1 Тогда
    ТекВызов = 0;
    КонецЕсли;
    ТекВызов = ТекВызов + 1;

    //------    Автоснятие резерва
    Если (ТекВызов % 5 = 0) Тогда
    ОжиданиеРезерв();
    КонецЕсли;

    //------    Сигнал или Завершение системы
    Если (ТекВызов % 3 = 0) Тогда
    ОжиданиеСигнал();
    КонецЕсли;

    //------    Заказ товара
    Если (ТекВызов % 37 = 0) Тогда
    ОжиданиеЗаказ();
    КонецЕсли;

    КонецПроцедуры    // Ожидание


    Процедура ПриНачалеРаботыСистемы()
    ОбработкаОжидания("Ожидание", 5);
    КонецПроцедуры    // ПриНачалеРаботыСистемы
     
  7. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Дайнеко, а что это за %? не встречал такого

    У меня так
    Код ( (Unknown Language)):
    Перем ТекЧас;
    Процедура ПриНачалеРаботыСистемы()
    ОбработкаОжидания("ПериодическиеПроцедуры",300);
    КонецПроцедуры

    Процедура ПериодическиеПроцедуры()
    Часы = "";
    ТекущееВремя(Часы);
    Если (ТекЧас = "") Тогда //первый запуск
    ВыгрузкаНаСайт();
    Изменениестатусов();
    Отчет30Дней();
    БитыеСсылки();
    ИначеЕсли Часы<ТекЧас Тогда// следующий день
    ВыгрузкаНаСайт();  
    Изменениестатусов();
    Отчет30Дней();
    БитыеСсылки();
    ИначеЕсли (ТекЧас+1 = Часы) Тогда//новый час
    ВыгрузкаНаСайт();
    Изменениестатусов();
    КонецЕсли;
    ОтправкаСМС();// каждые пять минут
    ТекЧас = Часы;
    КонецПроцедуры
     
  8. olga13

    olga13 Well-Known Member

    Регистрация:
    10 окт 2008
    Сообщения:
    208
    Симпатии:
    0
    Действительно, что это такое? Очень интересно.
     
  9. Hryv

    Hryv Гость

    Гы, я тоже не знал про %
    Век живи, век учись

    В ЖКК нашел
    % - остаток от деления, при выполнении оба операнда округляются до целого
     
  10. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    Ну, пацаны, вы даете! Изучайте матчасть. ;)

    Таким приемом я попытался сбалансировать нагрузку.
    Вот во фрагменте puh14 процедуры вызываются каждый час. И если уж бабахнуло, то отработали все процедуры сразу.
    Если они тяжеловесные, то у пользователя 1С замрет на несколько сек.

    У меня же:
    - проверка вызывается частенько (секунд 5)
    - меленькие можно вызывать каждый раз. Например, обмен сообщениями.
    - остальные, с коэффициентом. Получается частота их вызова в сек = 5*Кфц.
    - коэффициенты указываю не кратные друг другу. Лучше всего простые числа. Это гарантирует, что за один вызов Ожидания() сработает только одна проца. Хотя надежней и поставить после каждой "Возврат"

    С этим делом надо аккуратно. Представьте сидит человек 30 в базе. И у всех каждые н секунд бабахает вроде "Отчет30Дней()". А поставишь ОбработкаОжидания(,300); - потеряешь оперативность.
     
  11. olga13

    olga13 Well-Known Member

    Регистрация:
    10 окт 2008
    Сообщения:
    208
    Симпатии:
    0
    Вот и у меня возникла проблема - одна и та же обработка запускается у нескольких пользователей практически одновременно. А поскольку она создает документ, то в результате получается несколько одинаковых документов. ;)
    Как это побороть?
     
  12. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Списибо, буду знать про %.
    Насчет одновременно бабахнуло - у меня выгрузки, отправки мыла и т.п. повешены на отдельного пользователя "Бендер" - потому как робот. У остальных пользователей периодические отчеты вызываются - но я их на прямые запросы переписал, посему тормозов нет.

    Задайте что-то типа

    Процедура ПриНачалеРаботыСистемы()
    Если ИмяПользователя() = "Робот" Тогда
    ОбработкаОжидания("ПериодическиеПроцедуры",300);
    КонецЕсли;
    КонецПроцедуры

    Вешаете скриптик (или батник) запускающий нужную базу с этим пользователем в планировщик задач и все. У меня этот робот трудится в отдельной всегда работающей терминальной сессии, чтобы всегда подруился, посмотрел как работает.
     
  13. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    Сначала по понятиям:
    "Проверка" - периодический вызов процедуры указанной в ОбработкаОжидания().
    "Сработала процедура" - выполнилось в "Проверке" некоторое условие и запустилась вторая процедура, выполнившая некоторую полезную работу.

    Какие приемы:
    1) Первая ситуация: процедура должна срабатывать каждый час (каждые N минут). Если люди работают в терминале, то надо поставить срабатывание не проверкой часов компьютера: снял ТекущееВремя() и проверил, что минут=0 (думаю, понятно, почему). А по отсчету от момента запуска 1С. Например, если проверка вызывается каждые 10 сек., а полезную работу выполнять каждый час, то сверять, что счетчик вызовов кратен 3600/10. (Вот сдесь и нужен коварный знак "%"!)

    2) Вторая ситуация: сработать раз в день, но в установленное время. Чтобы часы на всех компах сработали по-разному, нужно сверять время, но добавить +/- несколько секунд. Например, прибавить "Пользователь.Код".

    3) После того как добились асинхронной работы пользователей, боремся с дублированием. Разумеется, надо продумать, что когда проц-ра отработает у одного пользователя, то когда она вызовется у другого пользователя, повторения результата быть не должно, новый док-т не запишется. Так у меня работает снятие резерва. У первого пользователя создался документ СнятиеРезерва, резерв снялся. У второго пытается сделать тоже, но 1С проанализировала, что резерва нет и пустой документ не записывает.
    Только нужна разбежка про времени. Считаем, что процедура отрабатыввает 2 сек. Значит проверка должна быть не чаше 5-10 сек.

    4) Прием с константой-семафором. Перед отработкой процедуры ставится что-то в константу. Другие программы видят ее и ничего не делают.

    5) Способ Puh14 с "зомби" - реальный. Но ориентирован на большую контору, которую, хорошо бы, и сам программист обслуживал.
     
  14. olga13

    olga13 Well-Known Member

    Регистрация:
    10 окт 2008
    Сообщения:
    208
    Симпатии:
    0
    Всем спасибо за советы, думаю, они мне помогут.
     
Загрузка...

Поделиться этой страницей