Flux d'événements. Comment contrôler et rendre l'événement inactif ? (+ résolu) - page 6

 
sergeev:

Et avez-vous déjà posé une nouvelle question ?

Il n'est pas approprié pour un modérateur de commencer une inondation. Pour clarifier. Lorsqu'un utilisateur (y compris un modérateur) ajoute un nouveau message à un fil de discussion, il est courant de l'appeler une "réponse". Même si c'est une réplique de nature sarcastique.

Par conséquent, une fois de plus, avec une précision : si vous le percevez comme un cirque, n'hésitez pas à le supprimer, ou essayez de soumettre un nouveau message sur ses mérites. En revanche, des informations inexactes peuvent induire les utilisateurs en erreur.

A ajouter. Je serai le premier à vous remercier s'il s'avère officiellement (si vous contribuez à le découvrir) que les événements des utilisateurs remplissent la file d'attente selon les anciennes règles.

 
Yedelkin:

Je vais ajouter. Je serai le premier à vous remercier s'il s'avère officiellement (si vous aidez à le découvrir) que les événements personnalisés remplissent la file d'attente selon les anciennes règles.

En gros, le traitement des événements n'a jamais changé. C'est juste que l'aide n'a pas été initialement rédigée correctement.
 
Rosh:
Grosso modo, le traitement des événements n'a jamais changé. C'est juste que ce n'était pas écrit correctement dans l'aide.
Merci. C'est une honte. Donc les anciennes règles du manuel sont fausses. Désolé pour la ringardise.
 
sergeev:

...

Le problème ne semble pas se reproduire, comme s'il n'était jamais arrivé.Alex, tu peux jeter un coup d'oeil dans ton bureau, si tu as une minute de libre. C'est-à-dire, comment il fonctionnera maintenant avec et sans votre add-on.
 

J'utilise activement le message d'inactivité créé dans chacune de mes applications. Tout fonctionne.

 
sergeev:

J'utilise activement le message d'inactivité créé dans chacune de mes applications. Tout fonctionne.

Il se peut que je n'aie plus de problème parce que je teste maintenant 3 caractères au lieu de 12 comme avant. J'écrirai si je trouve une dépendance. Merci.
 

sergeev: 

J'ai attrapé un virus.

Cela se produit en raison de l'envoi de l'événement EventChartCustom par le conseiller expert à lui-même. Il s'avère que cet envoi d'événement provoque la mise à jour du graphique par la fenêtre principale (ChartRedraw).

//---

J'ai fait un tel expert pour tester votre solution et en même temps j'ai essayé de résoudre le problème du clignotement très fréquent du texte lors de l'édition d'un objet 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"
     }
  }
//+------------------------------------------------------------------+

//---

Après avoir lancé le conseiller expert, vous verrez ce qui suit sur le graphique dans le coin supérieur gauche :

//---

En cliquant sur le bouton"START event_idle++", vous accédez à votre solution(Alex). Nous voyons le compteur event_idle++ s'incrémenter sur le graphique.

Tant que le bouton est enfoncé, votre code fonctionne. Mais il consomme beaucoup de ressources. La charge du CPU (testée sur un double cœur) varie de ~90% à ~100%. La charge du CPU varie de ~5% à ~10% avant le démarrage ou lorsque le bouton est relâché. En cliquant (avec le bouton gauche de la souris) sur le graphique, le compteur est remis à zéro.

La saisie de texte dans le champ de saisie ne provoque pas de scintillement, car au moment de la saisie, votre code est désactivé par la variable globale"On/Off event_idle++". C'est une béquille bien sûr, mais comme solution temporaire, c'est bien pour certaines solutions simples.

La charge du processeur n'est pas le seul problème. Lorsque le compteur fonctionne, les fenêtres du terminal de trading s'ouvrent rapidement, mais le redimensionnement des fenêtres est sensiblement ralenti. Pas toujours, mais ces moments existent.


Dossiers :
 
tol64:

La charge du processeur n'est pas le seul problème. Lorsque le compteur fonctionne, les fenêtres du terminal de trading s'ouvrent rapidement, mais le redimensionnement des fenêtres est sensiblement ralenti. Pas toujours, mais il y a de tels moments.

Le problème de la charge du CPU peut être résolu comme suit. Spécifiez que le compteur d'événements est mis à jour une fois par seconde. Nous ajoutons le code suivant :

Dans OnInit() :

EventSetTimer(1);

//---

Dans le corps du programme :

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

//---

Au code d'Alex(marqué en rouge) :

   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;
     }

//---

Dans le bloc du gestionnaire d'événementCHARTEVENT_CLICK(marqué en rouge) :

//+------------------------------------------------------------------+
//| СОБЫТИЕ_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
              );
     }

//---

Le bloc de gestion de l'événement CHARTEVENT_OBJECT_CLICK doit être modifié comme suit + L'état du bouton doit tout de même être vérifié, car il arrive qu'en appuyant "à tort" sur le bouton, celui-ci reste enfoncé, s'il était comme ça avant, mais le reste du code du bloc fonctionnera et la confusion commencera :

//+------------------------------------------------------------------+
//| СОБЫТИЕ_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;
           }
        }
     }

//---

Maintenant, ça devient plus intéressant. :)

//---

P.S. Si vous avez beaucoup de secondes, vous pouvez essayer de jouer avec GetTickCount().

 

Qu'est-ce que je peux dire ?

1. c 'est une charge pour l'unité centrale. Enlevez-le et il sera silencieux.

2. La boucle d'inactivité elle-même n'a pas d'effet notable sur le CPU.

3. Le problème du clignotement de l'edith n'est pas un problème avec une seule carte 0, mais un problème d'envoi d'un événement à la carte objet. Cela entraîne un redécoupage de la carte principale 0 et donne du scintillement.

 
sergeev:

Qu'est-ce que je peux dire ?

1. c'est une charge pour l'unité centrale. Enlevez-le et il sera silencieux.

2. La boucle d'inactivité elle-même n'a pas d'effet notable sur le CPU.

3. Le problème du clignotement de l'edith n'est pas un problème avec une seule carte 0, mais un problème d'envoi d'un événement à la carte objet. Cela entraîne une redéfinition de la carte principale 0 et donne du scintillement.

Merci pour cette précision. Je vais m'en occuper.