What actually triggers "Cannot set milisecond timer(n)" error and how to handle it?

 

It occurs when I call EventSetMillisecondTimer() and once it happens, the whole EA goes down.

The only official documentation I found is this: https://docs.mql4.com/eventfunctions/eventsetmillisecondtimer. There's, however, no detailed description of a proper usage of this function nor how to handle any errors.

Even though it's very rare, I still consider it a major problem, since a failure like this might cost a lot of money. Here's what I tried:

void SetMilisecondTimer(int interval)
{
   while(true)
   {
      if(EventSetMillisecondTimer(interval) == true)
         break;         
     
      Sleep(10);
   }
}

The problem here is, that once it returns false (so something went wrong), it loops endlessly until shutdown by timeout so there's no way of keeping the EA up after that.

Files:
Untitled.png  10 kb
 

You should evaluate the log and _LastError.

Then you should know what to do: Alert, or email, or sleep and re-try, or...

 
Carl Schreiber:

You should evaluate the log and _LastError.

Then you should know what to do: Alert, or email, or sleep and re-try, or...

That's exactly what I did. My point is - how to recover from this error once I receive it? Let's say it's probably caused by unavailability of system resources. Then ending the EA just doesn't make sense, because it's supposed to run nonstop.

How to set the timer again?

 
6xfngb5dgfe6d:

That's exactly what I did. My point is - how to recover from this error once I receive it? Let's say it's probably caused by unavailability of system resources. Then ending the EA just doesn't make sense, because it's supposed to run nonstop.

How to set the timer again?

You can only set ONE event timer at a time (per EA), not multiple ones.

Once you set it the first time, it will then generate the errors if you try again. There is no need to set it over and over again.

The only time you need to to that is if you want to change the interval, but you must first kill the current timer event before you set a new one.

 
Fernando Carreiro:

You can only set ONE event timer at a time (per EA), not multiple ones.

Once you set it the first time, it will then generate the errors if you try again. There is no need to set it over and over again.

The only time you need to to that is if you want to change the interval, but you must first kill the current timer event before you set a new one.

Thanks for the reply. This makes sense, but what if there's no active timer right now and I get this error? How can I try again then?
 
6xfngb5dgfe6d:
Thanks for the reply. This makes sense, but what if there's no active timer right now and I get this error? How can I try again then?

Check what the Error code is. Your code has no error handling in it. Always check the "_LastError" or the "GetLastError()" function when the event setting function fails and then Kill the TimerEvent if it is already set.

It is recommended that you only set the Timer interval once in the OnInit() handler and then kill it in the OnDeinit() handler.

Also, don't create an Endless loop for it, as you will just end-up causing an execution dead-lock!

 
Fernando Carreiro:

Check what the Error code is. Your code has no error handling in it. Always check the "_LastError" or the "GetLastError()" function when the event setting function fails and then Kill the TimerEvent if it is already set.

It is recommended that you only set the Timer interval once in the OnInit() handler and then kill it in the OnDeinit() handler.

Also, don't create an Endless loop for it, as you will just end-up causing an execution dead-lock!

I've printed out the error code as you recomended and got error 0/no error returned. As you can see, it still clearly fails to create the timer but also says, that there's no problem...

void SetMilisecondTimer(int interval)
{
   while(true)
   {
      if(EventSetMillisecondTimer(interval) == true)
         break;         
     
      Print("Error: " + GetLastError());
      EventKillTimer();
     
      Sleep(10);
   }
}
 
6xfngb5dgfe6d: I've printed out the error code as you recomended and got error 0/no error returned. As you can see, it still clearly fails to create the timer but also says, that there's no problem...

I am going to repeat the points again:

  1. Once you set the Timer Interval - stop trying to set it again! Your "SetMilisecondTimer" should not be called more than once, so check your code. Also the "EventSetTimer" and "EventSetMillisecondTimer" share the same event handler, so only use one of them. For debug purposes, print out when it is successful as well!
  2. Don't use an Endless Loop as you can cause a dead-lock.

EDIT: Also make sure that the interval you are setting is a valid one!

EDIT2: If after the above points, you still can't get it to work properly then consider the following:

  • Either post the complete source code file here on the forum, so that we can see what you are doing wrong ...
  • ... or, if you don't want to publicly show it, then consider sending me the file in PM and I will tell you what is wrong.
 
Fernando Carreiro:

I am going to repeat the points again:

  1. Once you set the Timer Interval - stop trying to set it again! Your "SetMilisecondTimer" should not be called more than once, so check your code. Also the "EventSetTimer" and "EventSetMillisecondTimer" share the same event handler, so only use one of them. For debug purposes, print out when it is successful as well!
  2. Don't use an Endless Loop as you can cause a dead-lock.

EDIT: Also make sure that the interval you are setting is a valid one!

EDIT2: If after the above points, you still can't get it to work properly then consider the following:

  • Either post the complete source code file here on the forum, so that we can see what you are doing wrong ...
  • ... or, if you don't want to publicly show it, then consider sending me the file in PM and I will tell you what is wrong.
if(EventSetMillisecondTimer(interval) == false)
{
   Print("Error " + GetLastError() + " occured.");
   
   //Now what do I do? I need that timer working
}

Thanks for those key points.

All I am trying to achieve is to restart it properly when it fails, but your recommendation is that I shouldn't set it again - what should I do then?

 
6xfngb5dgfe6d: Thanks for those key points. All I am trying to achieve is to restart it properly when it fails, but your recommendation is that I shouldn't set it again - what should I do then?

You are focusing too much on trying to restart it, and not enough on why you think it fails. It only fails for two possible reasons: either it has already been set or the value of the interval is invalid!

  1. Make sure that you have not set it before (even in the rest of your code). That is why I stated that you should also print out (debug) when it succeeds.
  2. Make sure that the value you are setting for the interval is actually correct and not some invalid value. You are not checking that!

Also, there is no need to check if it is "== false" or "== true". It is already a Boolean. Treat it as such.

// Example code only - Uncompiled & Untested

if( EventSetMillisecondTimer( interval ) )
{
   Print("EventSet: true" );
}
else
{
   Print("EventSet: false, Error: ", _LastError, ", Interval: ", interval );
}

PS! Remember that any value below 16ms is unreliable because of PC timer resolution, and in the back-tester values less than 1000ms are ignored.

The minimum interval of 1000 milliseconds is used in the strategy tester. In general, when the timer period is reduced, the testing time is increased, as the handler of timer events is called more often. When working in real-time mode, timer events are generated no more than 1 time in 10-16 milliseconds due to hardware limitations.
 
Fernando Carreiro: It only fails for two possible reasons: either it has already been set or the value of the interval is invalid!
FYI, third reason: MT4 indicator, placed on chart, no problem. Loaded by iCustom, call fails, no error at iCustom.
Reason: