Init()和DeInit()执行顺序 - 页 21

 
fxsaber:
这听起来像是胡说八道。指示器复制的计时器彼此之间没有任何关系。

500年前,地球是球形的说法在大多数人听来也是无稽之谈。
好吧,我现在要为一个计时器重做这个例子。
 
Nikolai Semko:
好的,我现在要为计时器重做这个例子。
你想表明旧的deinit状态下的EvenKillTimer会影响新的init中的EventSetTimer 吗?
 
Nikolai Semko:


在毫不含糊的情况下。

试试这个原始的例子。在切换TF时,你会明白 "独特性"。

在这个例子中,一个带有当前时间 和价格坐标的对象在OnInit中被创建。在OnCalculate中,这个对象与价格一起移动。

在OnDeinit中,它被简单地(逻辑地)删除。

当切换TF时,结果发现该物体出现后又消失了。
为什么会发生这种情况?
因为有时 旧TF的OnDeinit会删除在新TF的OnInit中已经创建的内容这不是一个错误!创建这个例子的程序员应该怎么想,而没有阅读这个分支?

在你的例子中,图形对象存在于所有的TF中,你只需要放大就可以看到它。
 
fxsaber:
你想表明旧的deinit状态下的EvenKillTimer会影响新的init中的EventSetTimer吗?

我错了。我很抱歉。我的错误。
的确,新TF的定时器变成了旧TF的可存活、不可杀的EventKillTimer。:)
附加的文件:
KillTimer.mq5  6 kb
 
Sergey Pavlov:
在你的例子中,图形对象在所有的TF中都存在,你只需要放大就可以看到它。

不,不是的。它有时被旧TF的Deunit移除。
 
Nikolai Semko:
事实上,新TF的定时器被证明是有弹性的,无法被旧TF的EventKillTimer杀死。:)
非常高兴我的妄想变成了一种妄想。
 
Nikolai Semko:

不,不是的。它有时被旧TF的Deinit删除。

要强制更新图形对象,请使用ChartRedraw() 命令来重绘图形。

将此添加到Init和Deinit中。

   ChartRedraw();
 
Sergey Pavlov:

在Init和Deinit中添加这个:ChartRedraw()


试过了。这不会改变情况,也不能改变,如果该对象已经被删除,ChartRedraw()将不会复活它。
我不排除这种新TF的OnInit和旧TF的OnDeinit执行顺序不明确的 "特殊性 "可能取决于硬件。由于不同的线程,不同的处理器与不同的协处理器架构--这一切都很复杂,而我并不擅长这个。但从这个主题来看,这个 "功能 "出现在我的电脑和其他人的电脑上,这是肯定的。
所以,你想说你在你的电脑上试过这个例子,当你切换TF时,你总是看到这个物体?
顺便说一下,我注意到,如果你把蜡烛图增加到最大尺寸,即屏幕上的条数最少,就很难让对象消失。我不得不切换了30次TF来删除这个对象(即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