이벤트의 흐름. 유휴 이벤트를 제어하고 만드는 방법은 무엇입니까? (+ 결정)

 

한 가지 문제가 있습니다. 특정 기능을 업데이트해야 하지만 MQL이 타이머로 제공하는 것보다 빠르며 1초 미만입니다.
솔루션 - OnChartEventEventChartCustom 자체에 이벤트를 보냅니다.

모든 것이 매우 빠르게 작동합니다. 그러나 메시지 큐가 긁어내지 못하는 두 번째 문제가 있었습니다. 넘친다.

즉, 예를 들어 개체를 클릭할 때 CHARTEVENT_OBJECT_CLICK 이벤트는 즉시 발생하지 않고 이전의 모든 이벤트가 대기열에서 제거된 후에만 발생합니다.
그리고 아시다시피 이벤트 큐는 EventChartCustom으로 꽉 막혀 있습니다.

일반적으로 일부 기능의 밀집된 제어 업데이트를 달성해야 하지만 동시에

- while(true)과 같은 무한 루프가 없었습니다.
- 차트 이벤트가 발생하는 즉시 OnChartEvent 가 응답하도록 합니다.

이 상황에서 어떻게 진행합니까? EventChartCustom 전송을 제어하는 다른 변형을 먹을 수 있습니까?

즉, MQL이 특정 함수를 1초 이상 자주 호출하지만 대기열 없이 강제로 호출하는 방법입니다.

----------

가장 간단한 솔루션(개발자의 참여)은 OnChartEvent 함수를 벗어나지 않고 이벤트 대기열에서 다음 이벤트를 수신할 수 있도록 하는 것입니다.

저것들. 내 EventChartCustom의 모든 빈 이벤트가 한 번에 긁어모으도록 합니다. 그리고 왼쪽 이벤트에 의해 큐가 로드되는 것을 허용하지 마십시오.

 

OnChartEvent 를 처리할 때만 이벤트를 보내는 경우 대기열은 논리적으로 오버플로되지 않아야 합니다. 당신은 모든 곳에서이 이벤트 케이스를 시작하지 않습니까?

이벤트 레이아웃을 통해 이벤트를 보낼 수도 있습니다. 저것들. 특정 이벤트에 대한 응답 이벤트를 보낸 사람에게 보내는 데만 필요한 칠면조 또는 다른 조언자가 있습니다.

 
TheXpert :

OnChartEvent 를 처리할 때만 이벤트를 보내는 경우 대기열은 논리적으로 오버플로되지 않아야 합니다.

아니, 그냥 흘러넘친다. EventChartCustom 은 OnChartEvent에서 호출됩니다 . 그리고 사건의 조밀한 흐름이 있습니다. 한편으로는 당신이 필요로 하는 것이고, 다른 한편으로는 차트 이벤트가 오랜 시간 동안 돌파됩니다.

패딩 이벤트를 통해 이벤트를 보낼 수도 있습니다. 저것들. 특정 이벤트에 대한 응답 이벤트를 보낸 사람에게 보내는 데만 필요한 칠면조 또는 다른 조언자가 있습니다.

그렇게 생각했지만 아무 것도 떠오르지 않았습니다. 교환 계획을 설명하시겠습니까?
 
sergeev :
그렇게 생각했지만 아무 것도 떠오르지 않았습니다. 교환 계획을 설명합니까?

칠면조가 있습니다 (다른 스트림, 아마도 더 나을 것입니다). 이벤트 캐치 1. 이벤트 발생 시 포스트백에 필요한 모든 정보를 전달하는 것이 바람직하다.

칠면조는 이벤트 2를 이벤트 1의 발신자에게 보냅니다.

어드바이저가 이벤트 2를 포착하고 다시 이벤트 1을 보내면 어드바이저는 이벤트 1에 전혀 반응하지 않습니다.

그리고 가짜 조언자를 통해 그것이 일반적으로 넌센스라면 잠을 잘 수 있습니다.

 

아이디어는 명확합니다. 하지만 작동하지 않습니다. 하나의 이벤트를 건너뛰는 것과 같습니다.

하지만 이렇게 간단한 알고리즘을 확인해보니

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

모든 이벤트가 정상적으로 작동합니다. 브레이크가 없습니다.

하지만 한 줄에 EventChartCustom 을 두 번(또는 그 이상) 넣으면,

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

그러면 두 번 브레이크가 걸립니다.

여기에서 모든 것이 제대로 작동한다는 결론을 내렸습니다. 내 코드에서 EventChartCustom 에 대한 이중 호출이 있습니다. 어딘가에, 그리고 이 사건은 축적된다.

코드를 살펴보겠습니다. 지금은 주제를 닫을 수 있습니다.

 
sergeev :

아이디어는 명확합니다. 하지만 작동하지 않습니다. 하나의 이벤트를 건너뛰는 것과 같습니다.

아니요. 예, 이벤트 1과 2의 차트가 다릅니다.

(1) 다른 스레드의 경우 이것이 훨씬 느리게 작동할 것이라는 의심이 있습니다.

(2) 조언자가 있으면 잘 수 있습니다.

글쎄, 2 배 (적어도) 느립니다.

 
свой 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() 
  {
//
  }
//+------------------------------------------------------------------+
이전 코드를 보았습니다 - 예
OnChartEvent 에서 스위치는 간섭하지 않으며 기본값은
EventSetCustomTimer
 
TheXpert :

아니요. 예, 이벤트 1과 2의 차트가 다릅니다.

(1) 다른 스레드의 경우 이것이 훨씬 느리게 작동할 것이라는 의심이 있습니다.

(2) 조언자가 있으면 잘 수 있습니다.

글쎄, 2 배 (적어도) 느립니다.


그들은 진실을 말합니다 - 저녁의 아침이 더 현명합니다. :) 문제를 해결했습니다. 그것은 심지어 우아하게 밝혀졌습니다.

- 보낸 메시지의 카운터를 입력 event_idle

- 이벤트를 보낼 때 이 카운터를 LPARAM EventChartCustom (chart, VM_IDLE, event_idle, 0, "")에 전달합니다.

- 그런 다음 OnChartEvent 핸들러에서 들어오는 LPARAM 매개변수가 현재 event_idle과 같아질 때까지 모든 VM_IDLE 메시지를 제거합니다.

이 정도

 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 , "" ); // отправили событие с указанием последнего счетчика

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

따라서 모두 철회될 것이기 때문에 이 이벤트에 대한 검색은 절대 없을 것입니다.

이제 이벤트 큐를 열거하지 않아도 속도가 꽤 만족스럽습니다. :)

 
sergeev :

... 하지만 메시지 큐가 긁히지 않는 두 번째 문제가 있었습니다. 넘친다.

질문에 대한 답을 찾을 수 없습니다. 이벤트 대기열의 오버플로가 RAM 크기에 어떤 영향을 줍니까? 이벤트 큐가 가득 차면 큐를 넘친 이벤트는 어디로 가나요? "기록에서 벗어난" 것으로 판명된 이벤트를 위해 예약된 RAM의 일부가 해제되었습니까?

내 질문이 용어상 일관성이 없을 수도 있지만 (나는) 문제의 본질을 전달하기를 바랍니다.

 
Yedelkin :

질문에 대한 답을 찾을 수 없습니다. 이벤트 대기열의 오버플로가 RAM 크기에 어떤 영향을 줍니까? 이벤트 큐가 가득 차면 큐를 넘친 이벤트는 어디로 가나요?

문제의 사실은 어디에도 없다는 것입니다. 축적하다.
 
sergeev :
문제의 사실은 어디에도 없다는 것입니다. 축적하다.

즉, 이벤트 큐가 오버플로되면 큐를 오버플로한 이벤트가 RAM을 "돌이킬 수 없을 정도로 소탕"하여 소비된 RAM의 크기를 점차적으로 늘리는 것입니까? 하지만 그건 틀렸어. "금전 등록기를 지나쳐 날아가는" 이벤트는 결국 그들을 위해 예약된 메모리를 해제해야 하는 것 같습니다.

... 1년 동안 이벤트 대기열의 크기가 얼마냐는 질문에 명확한 답을 얻지 못했습니다. 따라서 사용자 이벤트가 터미널의 이벤트 대기열을 넘지 않도록 얼마나 자주 사용자 이벤트 를 보내야 하는지는 아직 명확하지 않습니다...

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