Flujo de eventos. ¿Cómo controlar y hacer que el evento sea inactivo? (+ resuelto)

 

Hay un problema - Tengo que hacer la actualización de alguna función, pero más rápido que MQL en el temporizador - menos de 1 segundo.
Solución - hecho el envío de eventos a mí mismo - EventChartCustom en OnChartEvent.

Todo funciona muy rápido. Pero el segundo problema es que la cola de mensajes no tiene tiempo de limpiarse.

Por ejemplo, cuando se hace clic en el objeto, el evento CHARTEVENT_OBJECT_CLICK no vendrá a la vez, sino sólo después de que todos los eventos anteriores sean eliminados de la cola.
Y como comprenderás la cola de eventos está atascada con EventChartCustom.

Básicamente, necesitamos conseguir una actualización muy controlada de alguna función, pero al mismo tiempo

- no había un bucle interminable como el while (true)
- pero también que OnChartEvent responda tan pronto como se produzca el evento del gráfico.

¿Qué hacer en esta situación? ¿Tal vez haya otra opción con el control de envío de EventChartCustom?

En otras palabras - cómo hacer que MQL llame a alguna función más de 1 segundo, pero sin ninguna cola.

----------

La solución más fácil (pero con la participación del desarrollador) es permitir recibir el siguiente evento de la cola de eventos, pero sin salir de la función OnChartEvent.

Es decir, quiero que todos los eventos vacíos de mi EventChartCustom se limpien de una sola vez. Y no permitir cargar la cola con eventos de la izquierda.

 

Si sólo envías un evento cuando manejas OnChartEvent, la cola lógicamente no debería desbordarse. No se celebra este evento en todas partes, ¿verdad?

También puede enviar el evento a través del enrutamiento de eventos. Es decir, hay un indicador u otro Asesor Experto, que sólo es necesario para enviar eventos de respuesta a ciertos eventos al emisor.

 
TheXpert:

Si sólo se envía un evento cuando se procesa OnChartEvent, la cola lógicamente no debería desbordarse.

No, sólo se desborda. EventChartCustom es llamado en OnChartEvent. Y hay una densa corriente de eventos. Por un lado, es lo que necesitas, pero por otro lado, los eventos de la carta tardan mucho en llegar.

También puedes enviar el evento a través del pad de eventos. Es decir, hay un induke, u otro Asesor Experto, que sólo es necesario para enviar eventos de respuesta a determinados eventos al emisor.

Lo he pensado así, pero no se me ha ocurrido nada. ¿Describir el esquema de intercambio?
 
sergeev:
He pensado en ello, pero no se me ha ocurrido nada. Describa el sistema de intercambio.

Tenemos un indicador (diferentes hilos, puede ser mejor). Atrapa el evento 1. En el caso, es deseable pasar toda la información necesaria para ser enviado de vuelta.

Turquía envía el evento 2 al emisor del evento 1.

El EA capta el evento 2 y vuelve a enviar el evento 1, ante el evento 1 el EA no reacciona en absoluto.

Y si utilizamos un falso Asesor Experto, nos lo pasaremos bien durmiendo.

 

La idea es clara. pero no funcionará. sería como perder un solo evento.

Pero acabo de probar un algoritmo simple como este.

int rest=0;
int all=0;
bool click=false;
//------------------------------------------------------------------    OnInit
int OnInit() { EventChartCustom(0, 0, 0, 0, ""); return(0); }
//------------------------------------------------------------------    OnChartEvent
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
        if (id==CHARTEVENT_OBJECT_CLICK) click=!click;
        if (!click) { EventChartCustom(0, 0, 0, 0, ""); all++; }
        else rest++;
        
        string txt="all="+string(all)+"  rest="+string(rest);
        SetButton(0, "btn", 0, txt, clrWhite, clrDarkBlue, 150, 150, 200, 50, 0, 9, "Tahoma", click);
        ChartRedraw(0);
}
//------------------------------------------------------------------ SetButton
void SetButton(long achart, string name, int wnd, string text, color txtclr, color bgclr, int x, int y, int dx, int dy, int corn=0, int fontsize=8, string font="Tahoma", bool state=false)
{
        ObjectCreate(achart, name, OBJ_BUTTON, wnd, 0, 0); ObjectSetInteger(achart, name, OBJPROP_CORNER, corn); 
        ObjectSetString(achart, name, OBJPROP_TEXT, text); ObjectSetInteger(achart, name, OBJPROP_STATE, state);
        ObjectSetInteger(achart, name, OBJPROP_COLOR, txtclr); ObjectSetInteger(achart, name, OBJPROP_BGCOLOR, bgclr); ObjectSetInteger(achart, name, OBJPROP_BORDER_COLOR, clrNONE);
        ObjectSetInteger(achart, name, OBJPROP_FONTSIZE, fontsize); ObjectSetString(achart, name, OBJPROP_FONT, font);
        ObjectSetInteger(achart, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(achart, name, OBJPROP_YDISTANCE, y);
        ObjectSetInteger(achart, name, OBJPROP_XSIZE, dx); ObjectSetInteger(achart, name, OBJPROP_YSIZE, dy);
        ObjectSetInteger(achart, name, OBJPROP_SELECTABLE, false);
        ObjectSetInteger(achart, name, OBJPROP_BORDER_TYPE, 0);
        ObjectSetString(achart, name, OBJPROP_TOOLTIP, text);
}

Todos los eventos funcionan como deberían. No hay retrasos.

Pero si pones dos (o más) EventChartCustom en una línea,

if (!click) { EventChartCustom(0, 0, 0, 0, ""); EventChartCustom(0, 0, 0, 0, ""); all++; }

habrá el doble de retraso.

De ahí concluyo que todo funciona como debería, es mi código el que tiene doble llamada a EventChartCustom en alguna parte, y este evento se acumula.

Buscaré en el código. Por ahora, se puede cerrar el tema.

 
sergeev:

La idea es clara. pero no funcionará. sería como perderse un evento.

No. Sí, me refería a que los gráficos son diferentes para el evento 1 y 2

(1) Sospecho que funcionaría mucho más lento para diferentes hilos.

(2) puedes dormir si el asesor.

Bueno y 2 veces (por lo menos) más lento.

 
свой OnCustomTimer в миллисекундах


#define MSECTIMER 100
#define TIMEREVENT 111
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(60);
   EventSetCustomTimer(MSECTIMER);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EventSetCustomTimer(int msec) 
  {
   EventChartCustom(0,TIMEREVENT,msec,NULL,NULL);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   static uint lasttick=0;
   if(id==CHARTEVENT_CLICK) 
     {
      Print("Click");
     }

   if(id==CHARTEVENT_CUSTOM+TIMEREVENT) 
     {
      uint current=GetTickCount();
      if(lasttick+lparam<=current) 
        {
         lasttick=current;
         OnCustomTimer();
        }
     }
   EventSetCustomTimer(MSECTIMER);
  }
//+------------------------------------------------------------------+


void OnCustomTimer() 
  {
//
  }
//+------------------------------------------------------------------+
miró el código anterior - sí
y OnChartEvent podría utilizar un piggyback, que por defecto a
EventSetCustomTimer
 
TheXpert:

No. Sí, me refería a que los gráficos son diferentes para el evento 1 y 2

(1) Existe la sospecha de que funcionaría mucho más lento para diferentes hilos.

(2) Puedes dormir si el EA.

Bueno y 2 veces (por lo menos) más lento.


Es cierto lo que dicen: más sabio por la mañana. :) He resuelto el problema. Incluso ha funcionado con mucha elegancia.

- Introduzcamos el contador de mensajes enviados event_idle

- Al enviar el evento, envía este contador a LPARAM EventChartCustom(chart, VM_IDLE, event_idle, 0, "");

- y luego en el manejador de OnChartEvent, rastrillar todos los mensajes VM_IDLE hasta que el parámetro LPARAM entrante sea igual al event_idle actual.

así

ulong event_idle=0; bool bidle;
void OnChartEvent(int iview, int id, long lparam, double dparam, string sparam)
{
    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++;
        ChartRedraw(m_chart); // обновили чарт
        EventChartCustom(m_chart, VM_IDLE, (long)event_idle, 0, ""); // отправили событие с указанием последнего счетчика
        return; 
    }
    EventChartCustom(m_chart, VM_IDLE, (long)event_idle, 0, ""); // отправили событие  с указанием последнего счетчика

    /*
        обработка остальных событий
    */
}

De esta manera, nunca habrá un exceso de este evento, ya que todos serán raspados.

Ahora la velocidad está bien sin la enumeración de la cola event_idle :)

 
sergeev:

...Pero ha surgido un segundo problema: la cola de mensajes no se borra. se desborda.

No encuentro respuesta a la pregunta: ¿cómo afecta el desbordamiento de la cola de eventos al tamaño de la RAM? Si la cola de eventos resulta estar desbordada, ¿a dónde van los eventos que se desbordaron? ¿Se libera una parte de la memoria, reservada para aquellos acontecimientos que pasaron a estar "fuera de la historia"?

Quizá mis preguntas no sean terminológicamente correctas, pero (espero) captan la esencia del problema.

 
Yedelkin:

No encuentro respuesta a la pregunta: ¿cómo afecta el desbordamiento de la cola de eventos al tamaño de la RAM? Si la cola de eventos parece estar desbordada, ¿a dónde van los eventos que desbordaron la cola?

Esa es la cuestión: no lo hacen, se acumulan.
 
sergeev:
esa es la cuestión: no van a ninguna parte.

Es decir, si la cola de eventos se llena, los eventos que desbordan la cola "se comen" la RAM, aumentando gradualmente el tamaño de la RAM consumida? Pero esto es un error. Parece que los eventos que "pasaron la cola" deberían liberar finalmente la memoria reservada para ellos.

... Un año después todavía no he conseguido una respuesta coherente a la pregunta sobre el tamaño de la cola de eventos. Por lo tanto, todavía no está claro con qué frecuencia deben enviarse los eventos de usuario para que no desborden la cola de eventos del terminal...

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика - Документация по MQL5
Razón de la queja: