Flusso di eventi. Come controllare e rendere l'evento inattivo? (+ risolto) - pagina 6

 
sergeev:

E hai già fatto una nuova domanda?

Non è appropriato per un moderatore iniziare un flood. Per chiarire. Quando un utente (compreso un moderatore) aggiunge un nuovo post a una discussione, è comune chiamarlo "risposta". Anche se è una controreplica di natura sarcastica.

Quindi, ancora una volta, con una precisazione: se lo percepite come un circo, sentitevi liberi di cancellarlo, o di provare a presentare un nuovo messaggio sui suoi meriti. Informazioni imprecise, d'altra parte, possono indurre in errore gli utenti.

Da aggiungere. Sarò il primo a ringraziarti se si scopre ufficialmente (se aiuti a scoprirlo) che gli eventi utente riempiono la coda secondo le vecchie regole.

 
Yedelkin:

Aggiungo. Sarò il primo a ringraziarti se si scopre ufficialmente (se aiuti a scoprirlo) che gli eventi personalizzati riempiono la coda secondo le vecchie regole.

A grandi linee, la gestione degli eventi non è mai cambiata. È solo che l'aiuto non è stato scritto inizialmente in modo corretto.
 
Rosh:
Approssimativamente, la gestione degli eventi non è mai cambiata. È solo che originariamente non era scritto correttamente nell'aiuto.
Grazie. È un peccato. Quindi le vecchie regole del manuale sono sbagliate. Scusa per la nerditudine.
 
sergeev:

...

Il problema non sembra ripresentarsi, come se non fosse mai successo.Alex, potresti dare un'occhiata nel tuo ufficio, se hai un minuto libero. Cioè, come funzionerà ora con e senza il vostro add-on.
 

Uso attivamente il messaggio inattivo creato in ciascuna delle mie applicazioni. Tutto funziona.

 
sergeev:

Uso attivamente il messaggio inattivo creato in ciascuna delle mie applicazioni. Tutto funziona.

Forse non ho più il problema perché ora sto testando 3 caratteri invece di 12 come prima. Scriverò se trovo una dipendenza. Grazie.
 

sergeev: 

Ho preso una cimice.

Succede a causa dell'invio dell'evento EventChartCustom dall'Expert Advisor a se stesso. Si scopre che questo invio di eventi fa sì che la finestra principale aggiorni il grafico (ChartRedraw).

//---

Ho fatto un tale esperto per testare la tua soluzione e allo stesso tempo ho cercato di risolvere il problema con lo sfarfallio super frequente del testo durante la modifica di un oggetto 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"
     }
  }
//+------------------------------------------------------------------+

//---

Dopo aver lanciato l'Expert Advisor, vedrai quanto segue sul grafico in alto a sinistra:

//---

Cliccando sul pulsante"START event_idle++" accederai alla tua soluzione(Alex). Vediamo l'incremento del contatore event_idle++ proprio sul grafico.

Finché il pulsante è premuto, il vostro codice funzionerà. Ma consuma molte risorse. Il carico della CPU (testato su dual core) va dal ~90% al ~100%. Il carico della CPU varia da ~5% a ~10% prima dell'avvio o quando il pulsante viene rilasciato. Cliccando (con il tasto sinistro del mouse) sul grafico si azzera il contatore.

L'inserimento del testo nel campo di input non causa lo sfarfallio, perché al momento dell'inserimento il tuo codice è disabilitato dalla variabile globale"On/Off event_idle++". È una stampella ovviamente, ma come soluzione temporanea va bene per alcune soluzioni semplici.

Il carico della CPU non è l'unico problema. Quando il contatore è in funzione, le finestre del terminale di trading si aprono rapidamente, ma il ridimensionamento delle finestre rallenta notevolmente. Non sempre, ma questi momenti ci sono.


File:
 
tol64:

Il carico della CPU non è l'unico problema. Quando il contatore è in funzione, le finestre del terminale di trading si aprono rapidamente, ma il ridimensionamento delle finestre rallenta notevolmente. Non sempre, ma ci sono questi momenti.

Il problema del carico della CPU può essere risolto come segue. Specifica che il contatore degli eventi viene aggiornato una volta al secondo. Aggiungiamo il seguente codice:

In OnInit():

EventSetTimer(1);

//---

Nel corpo del programma:

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

//---

Al codice di Alex(segnato in rosso):

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

//---

Nel blocco gestore dell'eventoCHARTEVENT_CLICK(segnato in rosso):

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

//---

Il blocco gestore dell'evento CHARTEVENT_OBJECT_CLICK dovrebbe essere modificato come segue + Lo stato del pulsante dovrebbe essere controllato lo stesso, perché a volte anche premendolo "erroneamente" lo lascerà depresso, se prima era così, ma il resto del codice nel blocco funzionerà e inizierà la confusione:

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

//---

Ora diventa più interessante. :)

//---

P.S. Se avete molti secondi, potete provare a smanettare con GetTickCount().

 

Cosa posso dire

1. è un peso per la CPU. Rimuovetelo e sarà tranquillo.

2. Il ciclo idle in sé non ha alcun effetto evidente sulla CPU.

3. Il problema dello sfarfallio dell'edith non è un problema di un singolo grafico 0. È un problema di invio di un evento al grafico-oggetto. Questo fa sì che il grafico principale 0 venga ridisegnato e dia uno sfarfallio.

 
sergeev:

Cosa posso dire

1. è un peso per la CPU. Rimuovetelo e sarà tranquillo.

2. Il ciclo idle in sé non ha alcun effetto evidente sulla CPU.

3. Il problema dello sfarfallio dell'edith non è un problema con un solo grafico 0. È un problema con l'invio di un evento al grafico-oggetto. Questo fa sì che il grafico principale 0 venga ridisegnato e dia uno sfarfallio.

Grazie per il chiarimento. Ci darò un'occhiata.
Motivazione: