2018年11月10日土曜日
[MQL4] OnTick() と OnTimer() は同一スレッドで動いている
@MetaTrader 4.00 Build 1090
Expert Adviser の OnTick()
で何か重たい処理をしているとき1、OnTimer()
はどのように処理されるのか、調べてみました。
結論から言うと、以下のような動作をするようです。 (同一スレッド上で動いているか、少なくとも排他されている。)
OnTick()
の処理中にOnTimer()
のタイミングが来た場合、OnTick()
終了直後にOnTimer()
が実行される(OnTimer()
はペンディングされる)- ただし、2回以上ペンディングされたとしても、
OnTick()
終了直後に実行されるOnTimer()
は1回のみ - ペンディングされたとしても、
OnTimer()
が呼ばれるタイミングには影響しない(EventSetTimer()
が呼ばれた時点から指定間隔で呼ばれ続ける2)
この動作、逆の場合も当てはまるようです。
つまり、OnTimer()
で重たい処理をしていると、その間に呼ばれるはずだった OnTick()
が無視されることになります3。
また、OnTick()
で重たい処理をしていても、同じように OnTick()
が無視されます。
OnTick()
や OnTimer()
ではなるべく重たい処理をしないようにすべきですね。
かつ OnTimer()
の呼び出し頻度は少なめに。
確認環境
以下のような EA を作成し、タイミングをいろいろ変えて確認してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #property strict static uint count = 0; int OnInit() { //--- create timer EventSetTimer (1); // 1秒(本来こんなに高頻度で呼ぶべきではない) return (INIT_SUCCEEDED); } void OnDeinit( const int reason) { //--- destroy timer EventKillTimer (); } void OnTick() { count++; printf ( "OnTick %u start" , count); Sleep (3000); // 3秒待つ printf ( "OnTick %u end" , count); } void OnTimer() { Print ( "OnTimer" ); } |