Поток событий. Как контролировать и сделать событие idle ? (+ решено) - страница 6

 
sergeev:

а вы задали уже новый вопрос?

Негоже модератору начинать флуд. Поясняю. Добавление пользователем (в том числе и модератором) нового сообщения в тему общепринято называть "ответом". Даже если это реплика язвительного характера.

Поэтому, ещё раз, с уточнением: Если расцениваете, как цирк, - смело удаляйте. Или постарайтесь отправить новое сообщение по существу. Недостоверная же информация может ввести пользователей в заблуждение.

Добавлю. Первым же скажу Вам спасибо, если официально выяснится (если поспособствуете выяснению), что пользовательские события заполняют очередь по прежним правилам. 

 
Yedelkin:

Добавлю. Первым же скажу Вам спасибо, если официально выяснится (если поспособствуете выяснению), что пользовательские события заполняют очередь по прежним правилам. 

Грубо говоря, работа с событиями никогда и не менялась. Просто в справке было написано изначально не совсем верно.
 
Rosh:
Грубо говоря, работа с событиями никогда и не менялась. Просто в справке было написано изначально не совсем верно.
Спасибо. Жаль. Значит, прежние правила из Справочника - не верны. Извините за занудность.
 
sergeev:

...

Вроде бы проблема больше не возникает, как будто её и не было. Всё работает без тормозов.  Alex, пожалуйста, не могли бы у себя посмотреть, если будет свободная минутка. То есть, как сейчас будет работать  с Вашим дополнением и без него. 
 

Я активно пользуюсь в каждом своем приложении созданным idle сообщением. Все работает.

 
sergeev:

Я активно пользуюсь в каждом своем приложении созданным idle сообщением. Все работает.

Возможно у меня проблема больше не проявляется из-за того, что я сейчас тестирую 3 символа, а не 12, как раньше. Напишу, если найду зависимость. Спасибо.
 

sergeev: 

Баг выловил.

Такое происходит из за отправки события EventChartCustom из эксперта на этом чарте на самого себя. Получается, что эта отправка события вызывает обновление чарта (ChartRedraw) главного окна.

//--- 

Сделал вот такого эксперта для теста Вашего решения и заодно попробовал решить проблему со сверхчастым мерцанием текста во время редактирования объекта OBJ_EDIT

//--- 

//+------------------------------------------------------------------+
//|                                                 OnChartEvent.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
long chart_id=0;
string OnOff_event_idle="On/Off event_idle++";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   chart_id=ChartID();
//---
   if(!GlobalVariableCheck(OnOff_event_idle)) { GlobalVariableSet(OnOff_event_idle,1); }
//---
   Create_Edit(chart_id,0,"Edit_Area","HELLO",CORNER_LEFT_UPPER,"Arial",7,clrWhite,38,18,95,4,1,clrBlack);
   Create_Button(chart_id,0,"Start_event_idle","START event_idle++",ANCHOR_RIGHT_UPPER,CORNER_LEFT_UPPER,"Arial",8,clrWhite,clrFireBrick,clrNONE,130,26,4,28,1);
//---
   Comment("id: ",0,"\n",
           "event_idle++: ",event_idle
           );
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
   ObjectsDeleteAll(chart_id,-1,-1);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
bool bidle=false;
ushort VM_IDLE=500;
ulong event_idle=0; // счётчик событий
//---
void OnChartEvent(const int     id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(GlobalVariableGet(OnOff_event_idle)==1)
     {
      if(id==CHARTEVENT_CUSTOM+VM_IDLE)
        {
         // Если последнее посланное больше, чем пришедшее, то сразу выходим
         if(event_idle>(ulong)lparam || bidle)
           {
            bidle=event_idle>(ulong)lparam;
            //---
            if(bidle) { return; }
            //---
            event_idle=0;
           }
         //---
         event_idle++; // увеличили счётчик событий
         //---
         Comment("id: ",id,"\n",
                 "event_idle++: ",event_idle
                 );
         //---
         EventChartCustom(chart_id,VM_IDLE,(long)event_idle,0,""); return; // отправили событие с указанием последнего счетчика
        }
      //---
      EventChartCustom(chart_id,VM_IDLE,(long)event_idle,0,""); // отправили событие с указанием последнего счетчика
     }
//+------------------------------------------------------------------+
//| СОБЫТИЕ_CHARTEVENT_CLICK                                         |
//+------------------------------------------------------------------+
   if(id==CHARTEVENT_CLICK)
     {
      Print("Reset. Event_idle: ",event_idle);
      //---
      event_idle=0;
      //---
      Comment("id: ",id,"\n",
              "event_idle++: ",event_idle
              );
     }
//+------------------------------------------------------------------+
//| СОБЫТИЕ_CHARTEVENT_OBJECT_CLICK                                  |
//+------------------------------------------------------------------+
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam=="Edit_Area")
        {
         if((int)GlobalVariableGet(OnOff_event_idle)==0) { GlobalVariableSet(OnOff_event_idle,1); }
         if((int)GlobalVariableGet(OnOff_event_idle)==1) { GlobalVariableSet(OnOff_event_idle,0); }
        }
      //---
      if(sparam=="Start_event_idle")
        {
         if((int)GlobalVariableGet(OnOff_event_idle)==0) { GlobalVariableSet(OnOff_event_idle,1); ChartRedraw(); return; }
         if((int)GlobalVariableGet(OnOff_event_idle)==1) { GlobalVariableSet(OnOff_event_idle,0); ChartRedraw(); return; }
        }
     }
//+------------------------------------------------------------------+
//| CHARTEVENT_OBJECTS_ENDEDIT                                       |
//+------------------------------------------------------------------+
   if(id==CHARTEVENT_OBJECT_ENDEDIT)
     {
      if(ObjectGetInteger(chart_id,"Start_event_idle",OBJPROP_STATE)) { GlobalVariableSet(OnOff_event_idle,1); }
     }
  }
//+------------------------------------------------------------------+
//| СОЗДАНИЕ_ОБЪЕКТА_BUTTON                                          |
//+------------------------------------------------------------------+
void Create_Button(long   chrt_id,   // id графика
                   int    nmb_win,   // номер окна
                   string lable_nm,  // имя объекта
                   string rename,    // отображаемое имя
                   long   anchor,    // точка привязки
                   long   corner,    // угол привязки
                   string font_bsc,  // шрифт
                   int    font_size, // размер шрифта
                   color  font_clr,  // цвет шрифта
                   color  bg_color,  // цвет фона
                   color  brd_color, // цвет рамки
                   int    xsize,     // ширина
                   int    ysize,     // высота
                   int    x_dist,    // координата по шкале X
                   int    y_dist,    // координата по шкале Y
                   long   zorder)    // приоритет
  {
   if(ObjectCreate(chrt_id,lable_nm,OBJ_BUTTON,nmb_win,0,0)) // создание объекта
     {
      ObjectSetString(chrt_id,lable_nm,OBJPROP_TEXT,rename);             // установка имени
      ObjectSetString(chrt_id,lable_nm,OBJPROP_FONT,font_bsc);           // установка шрифта
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_COLOR,font_clr);         // установка цвета шрифта
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_BGCOLOR,bg_color);       // установка цвета фона
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_BORDER_COLOR,brd_color); // установка цвета фона
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_ANCHOR,anchor);          // установка точки привязки
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_CORNER,corner);          // установка угола привязки
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_FONTSIZE,font_size);     // установка размера шрифта
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_XSIZE,xsize);            // установка ширины X
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_YSIZE,ysize);            // установка высоты Y
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_XDISTANCE,x_dist);       // установка координаты X
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_YDISTANCE,y_dist);       // установка координаты Y
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_SELECTABLE,false);       // нельзя выделить объект, если FALSE
      ObjectSetInteger(chart_id,lable_nm,OBJPROP_ZORDER,zorder);         // Приоритет выше/ниже
      ObjectSetString(chrt_id,lable_nm,OBJPROP_TOOLTIP,"\n");            // нет всплывающей подсказки, если "\n"
     }
  }
//+------------------------------------------------------------------+
//| СОЗДАНИЕ_ОБЪЕКТА_EDIT                                            |
//+------------------------------------------------------------------+
void Create_Edit(long   chrt_id,   // id графика
                 int    nmb_win,   // номер окна (подокна)
                 string lable_nm,  // имя объекта
                 string text,      // отображаемый текст
                 long   corner,    // угол привязки
                 string font_bsc,  // шрифт
                 int    font_size, // размер шрифта
                 color  font_clr,  // цвет шрифта
                 int    xsize,     // ширина
                 int    ysize,     // высота
                 int    x_dist,    // координата по шкале X
                 int    y_dist,    // координата по шкале Y
                 long   zorder,    // приоритет
                 color  clr)       // цвет фона
  {
   if(ObjectCreate(chrt_id,lable_nm,OBJ_EDIT,nmb_win,0,0)) // создание объекта
     {
      ObjectSetString(chrt_id,lable_nm,OBJPROP_TEXT,text);            // установка имени
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_CORNER,corner);       // установка угла привязки
      ObjectSetString(chrt_id,lable_nm,OBJPROP_FONT,font_bsc);        // установка шрифта
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_FONTSIZE,font_size);  // установка размера шрифта
      ObjectSetInteger(chart_id,lable_nm,OBJPROP_COLOR,font_clr);     // цвет шрифта
      ObjectSetInteger(chart_id,lable_nm,OBJPROP_BGCOLOR,clr);        // цвет фона
      ObjectSetInteger(chart_id,lable_nm,OBJPROP_XSIZE,xsize);        // ширина
      ObjectSetInteger(chart_id,lable_nm,OBJPROP_YSIZE,ysize);        // высота
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_XDISTANCE,x_dist);    // установка координаты X
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_YDISTANCE,y_dist);    // установка координаты Y
      ObjectSetInteger(chrt_id,lable_nm,OBJPROP_SELECTABLE,false);    // нельзя выделить объект, если FALSE
      ObjectSetInteger(chart_id,lable_nm,OBJPROP_ZORDER,zorder);      // Приоритет выше/ниже
      ObjectSetString(chrt_id,lable_nm,OBJPROP_TOOLTIP,"\n");         // нет всплывающей подсказки, если "\n"
     }
  }
//+------------------------------------------------------------------+

//--- 

После запуска эксперта, на графике в левом верхнем углу увидим следующее:

 

 //---

Нажав на кнопку "START event_idle++" даём доступ к Вашему (Alex) решению. Видим, как счётчик event_idle++ увеличивает значение прямо на графике.

Пока кнопка нажата Ваш код будет работать. Правда ресурсы он кушает очень сильно. Загрузка процессора (тестировал на двух-ядерном) колеблется от ~90% до ~100%. До запуска или в момент, когда кнопка отжата, загрузка процессора от ~5% до ~10%. Клик (щелчок левой кнопки мыши) на графике сбрасывает счётчик в ноль.

Ввод текста в поле ввода не вызывает мерцания, так как в момент ввода Ваш код отключается с помощью глобальной переменной "On/Off event_idle++". Это костыль конечно, но как временное решение вполне подходит для некоторых простых решений.

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


 
Файлы:
 
tol64:

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

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

В OnInit():

EventSetTimer(1);

//--- 

В тело программы:

//+------------------------------------------------------------------+
//| ТАЙМЕР                                                           |
//+------------------------------------------------------------------+
long countSecond=0;
//---
void OnTimer()
  {
   if(GlobalVariableGet(OnOff_event_idle)==1)
     {
      countSecond++;
     }
  }

//---

В код Alex'a (отмечено красным):

   if(GlobalVariableGet(OnOff_event_idle)==1)
     {
      if(id==CHARTEVENT_CUSTOM+VM_IDLE && countSecond>0)
        {
         // Если последнее посланное больше, чем пришедшее, то сразу выходим
         if(event_idle>(ulong)lparam || bidle)
           {
            bidle=event_idle>(ulong)lparam;
            //---
            if(bidle) { return; }
            //---
            event_idle=0;
           }
         //---
         event_idle++; // увеличили счётчик событий
         //---
         Comment("id: ",id,"\n",
                 "event_idle++: ",event_idle
                 );
         //---
         // Отправили событие с указанием последнего счетчика
         EventChartCustom(chart_id,VM_IDLE,(long)event_idle,0,""); countSecond=0; return;
        }
      //---
      // Отправили событие с указанием последнего счетчика
      EventChartCustom(chart_id,VM_IDLE,(long)event_idle,0,""); countSecond=0;
     }

//---

В блок обработки событий  CHARTEVENT_CLICK (отмечено красным):

//+------------------------------------------------------------------+
//| СОБЫТИЕ_CHARTEVENT_CLICK                                         |
//+------------------------------------------------------------------+
   if(id==CHARTEVENT_CLICK)
     {
      Print("Reset. Event_idle: ",event_idle);
      //---
      event_idle=0;
      countSecond=0;
      //---
      Comment("id: ",id,"\n",
              "event_idle++: ",event_idle
              );
     }

//---

Блок обработки событий CHARTEVENT_OBJECT_CLICK редактируем следующим образом + Состояние кнопок всё таки нужно контролировать, так как иногда даже нажав на неё "как-то не так" она остаётся отжатой, если была до этого такой, но весь остальной код в блоке отработается и начнётся путаница:

//+------------------------------------------------------------------+
//| СОБЫТИЕ_CHARTEVENT_OBJECT_CLICK                                  |
//+------------------------------------------------------------------+
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam=="Edit_Area")
        {
         if((int)GlobalVariableGet(OnOff_event_idle)==0) { GlobalVariableSet(OnOff_event_idle,1); }
         if((int)GlobalVariableGet(OnOff_event_idle)==1) { GlobalVariableSet(OnOff_event_idle,0); }
        }
      //---
      if(sparam=="Start_event_idle")
        {
         if((int)GlobalVariableGet(OnOff_event_idle)==0)
           {
            countSecond=0;
            GlobalVariableSet(OnOff_event_idle,1);
            ObjectSetInteger(chart_id,"Start_event_idle",OBJPROP_STATE,true);
            //---
            ChartRedraw(); return;
           }
         //---
         if((int)GlobalVariableGet(OnOff_event_idle)==1)
           {
            countSecond=0;
            GlobalVariableSet(OnOff_event_idle,0);
            ObjectSetInteger(chart_id,"Start_event_idle",OBJPROP_STATE,false);
            //---
            ChartRedraw(); return;
           }
        }
     }

//---

Вот теперь всё интереснее. :)

//--- 

P.S. Если секунды много, то можно попробовать поколдовать с GetTickCount().

 

что могу сказать

1. грузит проц Comment. Убераете его и станет тихо. 

2. Сам по себе idle цикл не оказывает заметного влияния на проц.

3. Проблема с мерцанием эдита - это проблема не одного 0-чарта.  Это проблема отправки события на объекта-чарт. Это приводит к перерисовке главного 0-чарта и дает мерцание.

 
sergeev:

что могу сказать

1. грузит проц Comment. Убераете его и станет тихо. 

2. Сам по себе idle цикл не оказывает заметного влияния на проц.

3. Проблема с мерцанием эдита - это проблема не одного 0-чарта.  Это проблема отправки события на объекта-чарт. Это приводит к перерисовке главного 0-чарта и дает мерцание.

Спасибо за уточнение. Буду разбираться.