Init()和DeInit()执行顺序 - 页 21 1...141516171819202122232425262728 新评论 Nikolai Semko 2017.04.14 17:47 #201 fxsaber: 这听起来像是胡说八道。指示器复制的计时器彼此之间没有任何关系。 500年前,地球是球形的说法在大多数人听来也是无稽之谈。 好吧,我现在要为一个计时器重做这个例子。 fxsaber 2017.04.14 18:02 #202 Nikolai Semko: 好的,我现在要为计时器重做这个例子。 你想表明旧的deinit状态下的EvenKillTimer会影响新的init中的EventSetTimer 吗? Sergey Pavlov 2017.04.14 18:05 #203 Nikolai Semko: 在毫不含糊的情况下。试试这个原始的例子。在切换TF时,你会明白 "独特性"。在这个例子中,一个带有当前时间 和价格坐标的对象在OnInit中被创建。在OnCalculate中,这个对象与价格一起移动。在OnDeinit中,它被简单地(逻辑地)删除。当切换TF时,结果发现该物体出现后又消失了。 为什么会发生这种情况? 因为有时 旧TF的OnDeinit会删除在新TF的OnInit中已经创建的内容。这不是一个错误!创建这个例子的程序员应该怎么想,而没有阅读这个分支? 在你的例子中,图形对象存在于所有的TF中,你只需要放大就可以看到它。 Nikolai Semko 2017.04.14 18:07 #204 fxsaber: 你想表明旧的deinit状态下的EvenKillTimer会影响新的init中的EventSetTimer吗? 我错了。我很抱歉。我的错误。 的确,新TF的定时器变成了旧TF的可存活、不可杀的EventKillTimer。:) 附加的文件: KillTimer.mq5 6 kb Nikolai Semko 2017.04.14 18:11 #205 Sergey Pavlov: 在你的例子中,图形对象在所有的TF中都存在,你只需要放大就可以看到它。 不,不是的。它有时被旧TF的Deunit移除。 TheXpert 2017.04.14 18:23 #206 Nikolai Semko: 事实上,新TF的定时器被证明是有弹性的,无法被旧TF的EventKillTimer杀死。:) 非常高兴我的妄想变成了一种妄想。 Sergey Pavlov 2017.04.14 18:25 #207 Nikolai Semko: 不,不是的。它有时被旧TF的Deinit删除。要强制更新图形对象,请使用ChartRedraw() 命令来重绘图形。将此添加到Init和Deinit中。 ChartRedraw(); Nikolai Semko 2017.04.14 18:43 #208 Sergey Pavlov:在Init和Deinit中添加这个:ChartRedraw()。试过了。这不会改变情况,也不能改变,如果该对象已经被删除,ChartRedraw()将不会复活它。 我不排除这种新TF的OnInit和旧TF的OnDeinit执行顺序不明确的 "特殊性 "可能取决于硬件。由于不同的线程,不同的处理器与不同的协处理器架构--这一切都很复杂,而我并不擅长这个。但从这个主题来看,这个 "功能 "出现在我的电脑和其他人的电脑上,这是肯定的。 所以,你想说你在你的电脑上试过这个例子,当你切换TF时,你总是看到这个物体? 顺便说一下,我注意到,如果你把蜡烛图增加到最大尺寸,即屏幕上的条数最少,就很难让对象消失。我不得不切换了30次TF来删除这个对象(即DeUnit比Unit晚触发)。显然,这种 "特殊性 "受到螺纹性能的影响。这是作为一种假设,或者说是一种大声的思考。 Nikolai Semko 2017.04.14 18:53 #209 Комбинатор: 非常高兴我的妄想变成了一种妄想。:)这不是一个妄想,只是一个假设。 谢谢你的假设。感谢它和fxsaber,我对什么是指标副本有了新一轮的认识。计时器只是属于该副本,即使在TF发生变化时也会随着它一起死亡。但是,对象是自己生活的,即使它们是由指标的副本创建的,它们也只属于窗口。现在我明白了,在Deunit中写EventKillTimer 是没有意义的,无论如何,如果Deunit已经被调用,计时器就会死亡。 fxsaber 2017.04.14 21:35 #210 问题解决方案#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 1...141516171819202122232425262728 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
这听起来像是胡说八道。指示器复制的计时器彼此之间没有任何关系。
500年前,地球是球形的说法在大多数人听来也是无稽之谈。
好吧,我现在要为一个计时器重做这个例子。
好的,我现在要为计时器重做这个例子。
在毫不含糊的情况下。
试试这个原始的例子。在切换TF时,你会明白 "独特性"。
在这个例子中,一个带有当前时间 和价格坐标的对象在OnInit中被创建。在OnCalculate中,这个对象与价格一起移动。
在OnDeinit中,它被简单地(逻辑地)删除。
当切换TF时,结果发现该物体出现后又消失了。
为什么会发生这种情况?
因为有时 旧TF的OnDeinit会删除在新TF的OnInit中已经创建的内容。这不是一个错误!创建这个例子的程序员应该怎么想,而没有阅读这个分支?
你想表明旧的deinit状态下的EvenKillTimer会影响新的init中的EventSetTimer吗?
我错了。我很抱歉。我的错误。
的确,新TF的定时器变成了旧TF的可存活、不可杀的EventKillTimer。:)
在你的例子中,图形对象在所有的TF中都存在,你只需要放大就可以看到它。
不,不是的。它有时被旧TF的Deunit移除。
事实上,新TF的定时器被证明是有弹性的,无法被旧TF的EventKillTimer杀死。:)
不,不是的。它有时被旧TF的Deinit删除。
要强制更新图形对象,请使用ChartRedraw() 命令来重绘图形。
将此添加到Init和Deinit中。
ChartRedraw();
在Init和Deinit中添加这个:ChartRedraw()。
试过了。这不会改变情况,也不能改变,如果该对象已经被删除,ChartRedraw()将不会复活它。
我不排除这种新TF的OnInit和旧TF的OnDeinit执行顺序不明确的 "特殊性 "可能取决于硬件。由于不同的线程,不同的处理器与不同的协处理器架构--这一切都很复杂,而我并不擅长这个。但从这个主题来看,这个 "功能 "出现在我的电脑和其他人的电脑上,这是肯定的。
所以,你想说你在你的电脑上试过这个例子,当你切换TF时,你总是看到这个物体?
顺便说一下,我注意到,如果你把蜡烛图增加到最大尺寸,即屏幕上的条数最少,就很难让对象消失。我不得不切换了30次TF来删除这个对象(即DeUnit比Unit晚触发)。显然,这种 "特殊性 "受到螺纹性能的影响。这是作为一种假设,或者说是一种大声的思考。
非常高兴我的妄想变成了一种妄想。
:)这不是一个妄想,只是一个假设。
谢谢你的假设。感谢它和fxsaber,我对什么是指标副本有了新一轮的认识。计时器只是属于该副本,即使在TF发生变化时也会随着它一起死亡。但是,对象是自己生活的,即使它们是由指标的副本创建的,它们也只属于窗口。现在我明白了,在Deunit中写EventKillTimer 是没有意义的,无论如何,如果Deunit已经被调用,计时器就会死亡。
也就是说,整个问题是在任何指标的开头添加一行。
图书馆代码