Init() ve DeInit() yürütme sırası - sayfa 21

 
fxsaber :
Kulağa aptallık gibi geliyor. Gösterge kopyalama zamanlayıcılarının birbirleriyle hiçbir ilgisi yoktur.

500 yıl önce, çoğu insan için, Dünya'nın küresel olduğu ifadesi de saçma geliyordu.
Tamam, şimdi bu örneği bir zamanlayıcıya dönüştüreceğim.
 
Nikolai Semko :
Tamam, şimdi bu örneği bir zamanlayıcıya dönüştüreceğim.
Eski başlatma durumundaki EvenKillTimer'ın yeni başlatmadaki EventSetTimer'ı etkileyeceğini göstermek ister misiniz?
 
Nikolai Semko :


Peki, o tam olarak nerede?

Bu ilkel örneği kullanın. Ve TF'yi değiştirirken "benzersizliği" anlayacaksınız.

Bu örnekte, OnInit'te geçerli saat ve fiyatın koordinatlarıyla bir nesne oluşturulur. OnCalculate'de bu nesne fiyatla birlikte hareket eder.

OnDeinit'te basitçe (mantıklı olan) kaldırılır.

TF'yi değiştirirken, nesnenin göründüğü veya kaybolduğu ortaya çıkıyor.
Bu neden oluyor?
Çünkü bazen eski TF'nin OnDeinit'i, yeni TF'nin OnInit'inde önceden oluşturulmuş olanı siler. Bu bir hata değil! Bu örneği oluşturan ve bu konuyu okumayan programcı ne düşünmelidir?

Örneğinizde, grafik nesnesi tüm zaman dilimlerinde mevcuttur, onu görmek için ölçeği değiştirmeniz yeterlidir.
 
fxsaber :
Eski başlatma durumundaki EvenKillTimer'ın yeni başlatmadaki EventSetTimer'ı etkileyeceğini göstermek ister misiniz?

Yanlıştı. Üzgünüm. Berbat.
Gerçekten de, yeni TF'nin zamanlayıcısının, eski TF'nin EventKillTimer'ı tarafından öldürülmediği, inatçı olduğu ortaya çıktı. :)
Dosyalar:
KillTimer.mq5  6 kb
 
Sergey Pavlov :
Örneğinizde, grafik nesnesi tüm zaman dilimlerinde mevcuttur, onu görmek için ölçeği değiştirmeniz yeterlidir.

Hayır, doğru değil. Bazen eski TF'nin Deunit'i tarafından kaldırılır.
 
Nikolai Semko :
Gerçekten de, yeni TF'nin zamanlayıcısının, eski TF'nin EventKillTimer'ı tarafından öldürülmediği, inatçı olduğu ortaya çıktı. :)
Saçmalıklarımın saçma olduğu ortaya çıktığı için çok mutluyum
 
Nikolai Semko :

Hayır, doğru değil. Bazen eski TF'nin Deunit'i tarafından kaldırılır.

Grafik nesnelerinin güncellenmesini zorlamak için, grafiği yeniden çizmek için ChartRedraw() komutunu kullanın.

Bunu Init ve Deinit'e ekleyin:

   ChartRedraw ();
 
Sergey Pavlov :

Bunu Init ve Deinit'e ekleyin: ChartRedraw ();


Sınanmış. Bu durumu değiştirmez ve nesne zaten silinmişse ChartRedraw () onu diriltmez.
Yeni TF'nin OnInit'inin ve eski TF'nin OnDeinit'inin yürütme sırasının belirsizliğinin bu "özelliğinin" donanıma bağlı olabileceğini dışlamıyorum, Sergey. Çünkü farklı iş parçacıkları, farklı işlemci mimarilerine sahip farklı işlemciler - hepsi karmaşık ve bunda iyi değilim. Ama bu "özelliğin" benim bilgisayarımda ve başkalarının bilgisayarında bu konuya bakılırsa ortaya çıkması kesin.
Yani bu örneği bilgisayarınızda denediğinizi ve TF'yi değiştirdiğinizde her zaman nesneyi gördüğünüzü mü söylemek istiyorsunuz?
Bu arada, mumlar maksimum boyuta yükseltilirse, yani. ekranda minimum çubuk sayısı, nesnenin kaybolmasını sağlamak çok zordur. Nesnenin silinmesi için TF'yi 30 kez değiştirmek zorunda kaldım (yani Deunit, Unit'ten sonra çalıştı). Görünüşe göre bu "özellik" iş parçacıklarının performansını etkiliyor. Bir hipotez veya sesli düşünmek gibi.
 
Комбинатор :
Saçmalıklarımın saçma olduğu ortaya çıktığı için çok mutluyum

:) Saçma değildi, sadece bir hipotezdi.
Hipotez için teşekkürler. Onun ve fxsaber sayesinde, bir göstergenin kopyasının ne olduğunu anlama konusunda yeni bir tur geçirdim. Sadece zamanlayıcı bu kopyaya aittir ve TF'yi değiştirirken bile onunla birlikte ölür. Ve nesneler kendi başlarına yaşarlar, göstergenin bir kopyası tarafından oluşturulsalar bile sadece pencereye aittirler. Şimdi, EventKillTimer'ı Deunit'te yazmanın bir anlamı olmadığını anlıyorum, zaten DeUnit zaten çağrıldıysa zamanlayıcı ölecek.
 
Çözüm
 #include <Init_Sync.mqh> // Делает синхронизированными Init/Deinit индикаторов

#property indicator_chart_window

#property indicator_buffers 1
#property indicator_plots    1
#property indicator_color1   clrRed
#property indicator_type1   DRAW_LINE

input int Input = 0 ;

double Buffer[];

int OnInit ()
{
   SetIndexBuffer ( 0 , Buffer);
   Print ( "Init" );
   return ( INIT_SUCCEEDED );
}

void OnDeinit ( const int Reason )
{
   Print ( "DeInit" );
}

void OnChartEvent ( const int id,
                   const long & lparam,
                   const double & dparam,
                   const string & sparam )
{
}

void OnTimer ()
{
}

int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[] )
{
   ArrayCopy (Buffer, open, prev_calculated, prev_calculated);  
   return (rates_total);
}

Onlar. bütün sorun, herhangi bir göstergenin başına BİR satır eklemektir.


kitaplık kodu

 // Библиотека делает синхронизированными Init/Deinit индикаторов.
// В индикаторе обязательно должны быть int OnInit(), OnDeinit, OnTimer и OnChartEvent.
// Которые не используется - прописать пустыми.

struct INIT_SYNC
{
   const string GlobalName;

  INIT_SYNC( void ) : GlobalName(( string ):: ChartID () + :: MQLInfoString ( MQL_PROGRAM_NAME ))
  {
  }

   bool Check( void ) const
  {
     static bool FirstRun = true ;
     static bool FirstRunInit = true ;

     if (FirstRun && (!:: GlobalVariableCheck ( this .GlobalName)))
    {
      FirstRun = (:: GlobalVariableSet ( this .GlobalName, 0 ) == 0 );

       if (!FirstRun)
      {
        :: EventKillTimer ();

        :: OnInit ();
        FirstRunInit = false ;
      }
    }
     else if (FirstRun)
      :: EventSetMillisecondTimer ( 1 );
     else
      FirstRunInit = true ;

     return (FirstRun || !FirstRunInit);
  }

  ~INIT_SYNC( void )
  {
    :: GlobalVariableDel ( this .GlobalName);
  }
} Init_Sync;

#define CHECK_INIT_SYNC if (Init_Sync.Check()) return

int OnInit ( void )
{
  CHECK_INIT_SYNC INIT_SUCCEEDED ;

   return (::OldOnInit());
}

#define OnInit OldOnInit

int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[] )
{
  CHECK_INIT_SYNC prev_calculated;

   return (::OldOnCalculate(rates_total, prev_calculated, time, open, high, low, close, tick_volume, volume, spread));
}

#define OnCalculate OldOnCalculate

void OnTimer ( void )
{
  CHECK_INIT_SYNC;

  ::OldOnTimer();
}

#define OnTimer OldOnTimer

void OnDeinit ( const int Reason )
{
  CHECK_INIT_SYNC;

  ::OldOnDeinit(Reason);
}

#define OnDeinit OldOnDeinit

void OnChartEvent ( const int id,
                   const long & lparam,
                   const double & dparam,
                   const string & sparam )
{
  CHECK_INIT_SYNC;

  ::OldOnChartEvent(id, lparam, dparam, sparam);
}

#define OnChartEvent OldOnChartEvent
Dosyalar:
Init_Sync.mqh  3 kb