Init() 및 DeInit() 실행 순서 - 페이지 21

 
fxsaber :
바보 같은 소리. 표시기 복사 타이머는 서로 관련이 없습니다.

500년 전, 대부분의 사람들에게 지구가 구형이라는 말은 말도 안되는 소리처럼 들렸습니다.
자, 이제 이 예제를 타이머로 다시 만들겠습니다.
 
Nikolai Semko :
자, 이제 이 예제를 타이머로 다시 만들겠습니다.
이전 초기화 상태의 EvenKillTimer가 새 초기화의 EventSetTimer 에 영향을 미친다는 것을 표시하시겠습니까?
 
Nikolai Semko :


글쎄, 그녀는 정확히 어디에 있습니까?

이 원시적인 예를 사용하십시오. 그리고 TF를 전환할 때 "고유성"을 이해하게 될 것입니다.

이 예에서는현재 시간 과 가격의 좌표를 사용하여 OnInit에서 개체가 생성됩니다. OnCalculate에서 이 개체는 가격과 함께 움직입니다.

OnDeinit에서는 단순히 (논리적) 제거됩니다.

TF를 전환하면 개체가 나타나거나 사라집니다.
왜 이런 일이 발생합니까?
때로는 이전 TF의 OnDeinit가 새 TF의 OnInit에서 이미 생성된 것을 삭제하기 때문입니다. 이것은 버그가 아닙니다! 이 예제를 만들고 이 스레드를 읽지 않은 프로그래머는 어떻게 생각해야 할까요?

귀하의 예에서 그래픽 개체는 모든 시간 프레임에 존재하며, 이를 보려면 배율을 변경하기만 하면 됩니다.
 
fxsaber :
이전 초기화 상태의 EvenKillTimer가 새 초기화의 EventSetTimer에 영향을 미친다는 것을 표시하시겠습니까?

틀렸어. 죄송합니다. 망했어.
실제로 새 TF의 타이머는 끈기 있는 것으로 판명되었으며 이전 TF 의 EventKillTimer에 의해 죽지 않았습니다. :)
파일:
KillTimer.mq5  6 kb
 
Sergey Pavlov :
귀하의 예에서 그래픽 개체는 모든 시간 프레임에 존재하며, 이를 보려면 배율을 변경하기만 하면 됩니다.

아니요, 사실이 아닙니다. 때때로 오래된 TF의 Deunit에 의해 제거됩니다.
 
Nikolai Semko :
실제로 새 TF의 타이머는 끈기 있는 것으로 판명되었으며 이전 TF의 EventKillTimer에 의해 죽지 않았습니다. :)
내 헛소리가 헛소리로 밝혀져서 매우 기쁩니다.
 
Nikolai Semko :

아니요, 사실이 아닙니다. 때때로 오래된 TF의 Deunit에 의해 제거됩니다.

그래픽 개체를 강제로 업데이트하려면 ChartRedraw() 명령을 사용하여 차트를 다시 그립니다.

다음을 Init 및 Deinit에 추가합니다.

   ChartRedraw ();
 
Sergey Pavlov :

이것을 Init 및 Deinit에 추가하십시오. ChartRedraw ();


시험을 마친. 이것은 상황을 변경하지 않으며 개체가 이미 삭제된 경우 ChartRedraw ()가 이를 부활시키지도 않습니다.
Sergey, 새 TF의 OnInit 및 이전 TF의 OnDeinit 실행 순서가 모호하다는 이 "기능"이 하드웨어에 따라 달라질 수 있다는 점을 배제하지 않습니다. 왜냐하면 다른 스레드, 다른 보조 프로세서 아키텍처를 가진 다른 프로세서 - 모두 복잡하고 잘하지 못합니다. 그러나 이 "기능"이 이 스레드로 판단할 때 내 컴퓨터와 다른 사람의 컴퓨터에 나타난다는 사실은 확실합니다.
즉, 컴퓨터에서 이 예제를 시도했고 TF를 전환할 때 항상 개체를 보았다고 말하고 싶습니까?
그건 그렇고, 나는 양초가 최대 크기로 증가하면, 즉 화면의 최소 막대 수에서는 개체가 사라지는 것을 달성하기가 매우 어렵습니다. 개체를 삭제하려면 TF를 30번 전환해야 했습니다(즉, Deunit이 Unit보다 늦게 작동함). 분명히 이 "기능"은 스레드의 성능에 영향을 미칩니다. 그것은 가설이나 큰 소리로 생각하는 것과 같습니다.
 
Комбинатор :
내 헛소리가 헛소리로 밝혀져서 매우 기쁩니다.

:) 말도 안되는 소리가 아니라 가설일 뿐이었다.
가설 감사합니다. 그녀와 fxsaber 덕분에 지표의 사본이 무엇인지 새롭게 이해할 수 있었습니다. 타이머가 이 복사본에 속해 있고 TF를 변경해도 타이머와 함께 죽는다는 것뿐입니다. 그리고 개체는 자체적으로 존재하며 표시기의 복사본에 의해 생성되더라도 창에만 속합니다. 이제 Deunit에 EventKillTimer 를 처방하는 것이 의미가 없다는 것을 이해합니다. 어쨌든 DeUnit이 이미 호출된 경우 타이머가 죽을 것입니다.
 
해결책
 #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);
}

저것들. 전체 문제는 표시기의 시작 부분에 한 줄을 추가하는 것입니다.


라이브러리 코드

 // Библиотека делает синхронизированными 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
파일:
Init_Sync.mqh  3 kb
사유: