Event-Stream. Wie kann man das Ereignis kontrollieren und in den Leerlauf versetzen? (+ gelöst) - Seite 6

 
sergeev:

Und haben Sie schon eine neue Frage gestellt?

Es ist nicht angebracht, dass ein Moderator eine Flut auslöst. Zur Klarstellung. Wenn ein Benutzer (einschließlich eines Moderators) einen neuen Beitrag zu einem Thema hinzufügt, ist es üblich, dies als "Antwort" zu bezeichnen. Selbst wenn es sich um eine sarkastische Erwiderung handelt.

Deshalb noch einmal zur Klarstellung: Wenn Sie es als Zirkus empfinden, können Sie es gerne löschen oder versuchen, eine neue Nachricht in der Sache zu verfassen. Ungenaue Informationen hingegen können die Nutzer in die Irre führen.

Zum Hinzufügen. Ich werde der Erste sein, der sich bei Ihnen bedankt, wenn sich offiziell herausstellt (falls Sie dazu beitragen, dies herauszufinden), dass Benutzerereignisse die Warteschlange nach den alten Regeln füllen.

 
Yedelkin:

Ich füge hinzu. Ich werde der Erste sein, der sich bei Ihnen bedankt, wenn sich offiziell herausstellt (falls Sie dabei helfen, das herauszufinden), dass benutzerdefinierte Ereignisse die Warteschlange nach den alten Regeln füllen.

Grob gesagt hat sich die Handhabung der Ereignisse nie geändert. Es ist nur so, dass die Hilfe anfangs nicht ganz richtig geschrieben war.
 
Rosh:
Grob gesagt, hat sich die Handhabung von Ereignissen nie geändert. Es ist nur so, dass es ursprünglich in der Hilfe nicht richtig geschrieben war.
Ich danke Ihnen. Das ist eine Schande. Die alten Regeln des Handbuchs sind also falsch. Entschuldigen Sie, dass ich Ihnen auf die Nerven gehe.
 
sergeev:

...

Das Problem scheint nicht mehr aufzutreten, als wäre es nie geschehen.Alex, könntest du bitte einen Blick in dein Büro werfen, wenn du eine freie Minute hast. Das heißt, wie es jetzt mit und ohne Ihr Add-on funktionieren wird.
 

Ich verwende aktiv die Leerlaufmeldung, die in jeder meiner Anwendungen erstellt wird. Alles funktioniert.

 
sergeev:

Ich verwende aktiv die Leerlaufmeldung, die in jeder meiner Anwendungen erstellt wird. Alles funktioniert.

Möglicherweise habe ich das Problem nicht mehr, weil ich jetzt 3 statt wie bisher 12 Zeichen teste. Ich schreibe, wenn ich eine Abhängigkeit finde. Danke.
 

sergeev: 

Ich habe mir einen Käfer eingefangen.

Dies geschieht durch das Senden des Ereignisses EventChartCustom vom Expert Advisor an sich selbst. Es stellt sich heraus, dass dieses Senden des Ereignisses die Aktualisierung des Diagramms (ChartRedraw) des Hauptfensters bewirkt.

//---

Ich habe einen solchen Experten erstellt, um Ihre Lösung zu testen und gleichzeitig versucht, das Problem mit dem sehr häufigen Flackern des Textes beim Bearbeiten eines OBJ_EDIT-Objekts zu lösen.

//---

//+------------------------------------------------------------------+
//|                                                 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"
     }
  }
//+------------------------------------------------------------------+

//---

Nach dem Start des Expert Advisors sehen Sie auf dem Chart in der oberen linken Ecke folgendes:

//---

Wenn Sie auf die Schaltfläche"START event_idle++" klicken, gelangen Sie zu Ihrer(Alex-)Lösung. Der Zähler event_idle++ wird direkt im Diagramm erhöht.

Solange die Taste gedrückt wird, funktioniert Ihr Code. Aber es verbraucht eine Menge Ressourcen. Die CPU-Belastung (getestet auf einem Dual-Core-System) reicht von ~90% bis ~100%. Die CPU-Last liegt zwischen ~5% und ~10% vor dem Start oder wenn die Taste losgelassen wird. Durch Klicken (Linksklick) auf das Diagramm wird der Zähler auf Null zurückgesetzt.

Die Eingabe von Text in das Eingabefeld verursacht kein Flackern, da Ihr Code im Moment der Eingabe durch die globale Variable"On/Off event_idle++" deaktiviert wird. Es ist natürlich eine Krücke, aber als vorübergehende Lösung ist es für einige einfache Lösungen in Ordnung.

Die CPU-Auslastung ist nicht das einzige Problem. Wenn der Zähler läuft, öffnen sich die Fenster des Handelsterminals schnell, aber die Größenänderung der Fenster verlangsamt sich merklich. Nicht immer, aber solche Momente gibt es.


Dateien:
 
tol64:

Die CPU-Auslastung ist nicht das einzige Problem. Wenn der Zähler läuft, öffnen sich die Fenster des Handelsterminals schnell, aber die Größenänderung der Fenster verlangsamt sich merklich. Nicht immer, aber es gibt solche Momente.

Das Problem der CPU-Last kann wie folgt gelöst werden. Geben Sie an, dass der Ereigniszähler einmal pro Sekunde aktualisiert wird. Wir fügen den folgenden Code hinzu:

In OnInit():

EventSetTimer(1);

//---

Im Hauptteil des Programms:

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

//---

Zu Alex' Code (rot markiert):

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

//---

ImCHARTEVENT_CLICK-Ereignishandlerblock(rot markiert):

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

//---

Der CHARTEVENT_OBJECT_CLICK-Ereignishandler-Block sollte wie folgt bearbeitet werden + Der Zustand des Buttons sollte trotzdem überprüft werden, denn manchmal bleibt er auch bei "falschem" Drücken gedrückt, wenn er vorher so war, aber der Rest des Codes im Block funktioniert und die Verwirrung beginnt:

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

//---

Jetzt wird es noch interessanter. :)

//---

P.S. Wenn Sie sehr viele Sekunden haben, können Sie versuchen, mit GetTickCount() zu fummeln.

 

Was soll ich sagen

1. Es ist eine Belastung für die CPU. Entfernen Sie es und es wird leise sein.

2. Die Leerlaufschleife selbst hat keine spürbaren Auswirkungen auf die CPU.

3. Das Problem mit dem Flackern des Edith ist kein Problem mit einem einzelnen 0-Diagramm, sondern mit dem Senden eines Ereignisses an das Objektdiagramm. Dadurch wird das Hauptdiagramm 0 neu gezeichnet und flackert.

 
sergeev:

Was soll ich sagen

1. Es ist eine Belastung für die CPU. Entfernen Sie es und es wird leise sein.

2. Die Leerlaufschleife selbst hat keine spürbaren Auswirkungen auf die CPU.

3. Das Problem mit dem Flackern des Edith ist kein Problem mit einem einzelnen 0-Diagramm, sondern mit dem Senden eines Ereignisses an das Objektdiagramm. Dadurch wird das Hauptdiagramm 0 neu gezeichnet und flackert.

Danke für die Klarstellung. Ich werde es mir ansehen.