Olayların akışı. Boşta bir olay nasıl kontrol edilir ve yapılır? (+ karar verildi)

 

Bir sorun var - belirli bir işlevi güncellemeniz gerekiyor, ancak zamanlayıcı ile MQL'nin sunduğundan daha hızlı - 1 saniyeden az.
Çözüm - kendisine bir olay gönderme - OnChartEvent'te EventChartCustom .

Her şey çok hızlı çalışıyor. Ancak mesaj kuyruğunun tırmıklamayı başaramadığı ikinci bir sorun vardı. taşar.

Yani, örneğin, bir nesneye tıklandığında, CHARTEVENT_OBJECT_CLICK olayı hemen gelmez, ancak yalnızca önceki tüm olaylar kuyruktan kaldırıldıktan sonra gelir.
Ve anladığınız gibi, olay kuyruğu EventChartCustom ile sıkıca tıkanmış.

Genel olarak, bazı işlevlerin yoğun kontrollü bir güncellemesini elde etmeniz gerekir, ancak aynı zamanda

- while (true) gibi sonsuz bir döngü yoktu
- aynı zamanda OnChartEvent'in grafik olayı gerçekleşir gerçekleşmez yanıt vermesi için.

Bu durumda nasıl hareket edilir? EventChartCustom gönderme kontrolü ile diğer varyantları yiyebilir mi?

Başka bir deyişle, MQL'yi belirli bir işlevi 1 saniyeden daha sık, ancak herhangi bir sıra olmadan çağırmaya zorlama.

----------

En basit çözüm (ancak geliştiricilerin katılımıyla), bir sonraki olayı olay kuyruğundan, ancak OnChartEvent işlevinden ayrılmadan almayı mümkün kılmaktır.

Onlar. böylece EventChartCustom'umdaki tüm boş olaylar bir seferde tırmıklanır. Ve kuyruğun sol olaylar tarafından yüklenmesine izin vermeyin.

 

Olay yalnızca OnChartEvent işlendiğinde gönderilirse, sıra mantıksal olarak taşmamalıdır. Her yerde bu olay bir dava başlatmak değil mi?

Ayrıca bir dolgu olayı aracılığıyla da bir olay gönderebilirsiniz. Onlar. gönderene yalnızca belirli olaylara yanıt olayları göndermek için gerekli olan bir hindi veya başka bir danışman var.

 
TheXpert :

Olay yalnızca OnChartEvent işlendiğinde gönderilirse, sıra mantıksal olarak taşmamalıdır.

Hayır, sadece kendini aşıyor. EventChartCustom , OnChartEvent'te çağrılır. Ve yoğun bir olay akışı var. Bir yanda neye ihtiyacınız var, diğer yanda ise grafik olayları uzun bir süre ara veriyor.

Ayrıca bir dolgu olayı aracılığıyla da bir olay gönderebilirsiniz. Onlar. gönderene yalnızca belirli olaylara yanıt olayları göndermek için gerekli olan bir hindi veya başka bir danışman var.

Ben de öyle düşündüm ama hiçbir şey çıkmadı. Değişim planını açıklayın?
 
sergeev :
Ben de öyle düşündüm ama hiçbir şey çıkmadı. Değişim planını açıklar mısınız?

Hindi var (farklı akışlar, muhtemelen daha iyi olacak). Olayları yakalar 1. Bir olayda, geri gönderme için gerekli tüm bilgilerin iletilmesi istenir.

Türkiye, olay 2'yi olay 1'in göndericisine gönderir.

Danışman olay 2'yi yakalar ve tekrar olay 1'i gönderir, danışman olay 1'e hiç tepki vermez.

Ve eğer sahte bir danışman aracılığıyla bu genellikle saçmasa, uyuyabilirsin.

 

Fikir açık. ama çalışmayacak. bir olayı atlamak gibi olacak.

Ama böyle basit bir algoritmayı kontrol ettim

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

Tüm olaylar olması gerektiği gibi çalışır. Fren yok.

Ancak bir satıra iki kez (veya daha fazla) EventChartCustom koyarsanız ,

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

sonra iki kez fren yapacaktır.

Buradan her şeyin olması gerektiği gibi çalıştığı sonucuna varıyorum, kodumda EventChartCustom'a çift çağrım var bir yerde ve bu olay birikir.

koda bakacağım. Şimdilik konu kapanabilir.

 
sergeev :

Fikir açık. ama çalışmayacak. bir olayı atlamak gibi olacak.

Numara. Evet, 1. ve 2. olaylar için çizelgelerin farklı olduğunu kastetmiştim.

(1) Farklı iş parçacıkları için bunun çok daha yavaş çalışacağına dair bir şüphe var.

(2) danışman varsa uyuyabilir.

Eh, 2 kat (en az) daha yavaş.

 
свой 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() 
  {
//
  }
//+------------------------------------------------------------------+
önceki koda baktım - evet
ve OnChartEvent'te anahtar karışmaz, varsayılanı
EventSetCustomTimer
 
TheXpert :

Numara. Evet, 1. ve 2. olaylar için çizelgelerin farklı olduğunu kastetmiştim.

(1) Farklı iş parçacıkları için bunun çok daha yavaş çalışacağına dair bir şüphe var.

(2) danışman varsa uyuyabilir.

Eh, 2 kat (en az) daha yavaş.


Gerçeği söylüyorlar - akşamın sabahı daha akıllıca. :) Sorunu çözdüm. Hatta zarif çıktı.

- gönderilen mesajların sayacını girin event_idle

- bir olay gönderirken, bu sayacı LPARAM EventChartCustom'a (chart, VM_IDLE, event_idle, 0, "");

- ve sonra OnChartEvent işleyicisinde gelen LPARAM parametresi mevcut event_idle değerine eşit olana kadar tüm VM_IDLE mesajlarını kaldırırız.

aşağı yukarı böyle

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

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

dolayısıyla bu olay için hiçbir zaman arama yapılmayacaktır, çünkü hepsi geri çekilecektir.

Şimdi, olay kuyruğunu saymadan bile hız oldukça tatmin edici :)

 
sergeev :

... Ama ikinci bir sorun daha vardı ki mesaj kuyruğunun ayıklanamamasıydı. taşar.

Şu soruya cevap bulamıyorum: Olay kuyruğunun taşması RAM'in boyutunu nasıl etkiler? Olay kuyruğu doluysa kuyruğu taşan olaylar nereye gidiyor? "Tarih dışı" olduğu ortaya çıkan olaylar için ayrılan RAM'in bir kısmı serbest mi kalıyor?

Belki sorularım terminolojik olarak tutarlı değildir, ancak (umarım) sorunun özünü aktarır.

 
Yedelkin :

Şu soruya cevap bulamıyorum: Olay kuyruğunun taşması RAM'in boyutunu nasıl etkiler? Olay kuyruğu doluysa kuyruğu taşan olaylar nereye gidiyor?

işin gerçeği hiçbir yerde. biriktirmek.
 
sergeev :
işin gerçeği hiçbir yerde. biriktirmek.

Yani, olay kuyruğu taşıyorsa, sırayı aşan olaylar RAM'i "geri dönülmez şekilde yutar", tüketilen RAM'in boyutunu kademeli olarak arttırır mı? Ama bu yanlış. Görünüşe göre, "yazar kasanın yanından uçup giden" olaylar, sonunda onlar için ayrılmış hafızayı serbest bırakmalıdır.

... Bir yıl boyunca olay kuyruğunun boyutu nedir sorusuna net bir cevap alamadım. Buna göre, terminalin olay kuyruğunu taşmamaları için kullanıcı olaylarının ne sıklıkta gönderilmesi gerektiği hala net değil...

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