1

I am trying to refresh my frame every 17ms with a timer.

Timer timer = new Timer(17);
timer.Elapsed += ResetFrame;
timer.Start();

But instead of waiting for 17ms and then repeating, it waited for the frame refresh to complete and then wait for 17msfor the next repeat. This causes the frame to be refreshed every 28ms. How to synchronize it with real time?

Mido
  • 341
  • 2
  • 15
  • 3
    Your UI thread is busy executing your handler (which refreshes the frame I assume). How is it going to keep executing your handler and start executing it again too, all at the same time? You could have an [async handler](https://stackoverflow.com/q/39260486/11683), but I doubt the result will be what you expect it to be. – GSerg Jul 11 '20 at 11:06
  • 17ms is delay between end of previous handler and start of next, not a delay from start to start i guess. – aepot Jul 11 '20 at 11:13
  • 1
    @aepot [Not really](https://stackoverflow.com/a/10471354/11683). – GSerg Jul 11 '20 at 11:18
  • [Timer accuracy](https://stackoverflow.com/questions/9228313/most-accurate-timer-in-net) – aepot Jul 11 '20 at 11:26
  • What `Timer` do you use ? From what namespace ? –  Jul 11 '20 at 11:26
  • 1
    @OlivierRogier I'm using `System.Timers`; – Mido Jul 11 '20 at 11:27
  • Have you tried the timer in `System.Threading` ? https://learn.microsoft.com/dotnet/api/system.threading.timer –  Jul 11 '20 at 11:30
  • 1
    Found that: https://stackoverflow.com/questions/9228313/most-accurate-timer-in-net & http://ideveloper-dotnet.blogspot.com/2013/07/real-time-timer-in-c.html & https://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer & https://github.com/SunsetQuest/Precision-Repeat-Action-On-Interval-Async-Method/blob/master/Program.cs –  Jul 11 '20 at 11:30
  • 1
    @OlivierRogier The code of the https://ideveloper-dotnet.blogspot.com/2013/07/real-time-timer-in-c.html solved my problem. Thank you. – Mido Jul 11 '20 at 12:10

1 Answers1

2

To have a real time timer having a very short interval, you can take a look at this article:

Real Time Timer in C#

In Dot Net, following timers are not real time.

System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer

Means if you want to run your code at every 100 millisecond then above timer fire even around 110 millisecond or later. Windows is not a real time OS because of this .Net is also not a real time.

To create a real time timer in C# you have to write custom code that can hold CPU to run your code at right time.

class Program
{
   static void Main(string[] args)
  {
    Console.ReadLine();
    Console.WriteLine("Running");
    RealTimeTimerTest obj = new RealTimeTimerTest();
 
    obj.Run();
  }
}
 
public class RealTimeTimerTest
{
   List<DateTime> lst = new List<DateTime>();
  System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
 
  public void Run()
  {
    int Tick = 100;
    int Sleep = Tick - 20;
    long OldElapsedMilliseconds = 0;
    sw.Start();

    while (sw.IsRunning)
    {
      long ElapsedMilliseconds = sw.ElapsedMilliseconds;
      long mod = (ElapsedMilliseconds % Tick);

      if (OldElapsedMilliseconds != ElapsedMilliseconds && (mod == 0 || ElapsedMilliseconds > Tick))
      {

        //-----------------Do here whatever you want to do--------------Start
        lst.Add(DateTime.Now);
        //-----------------Do here whatever you want to do--------------End

        //-----------------Restart----------------Start
        OldElapsedMilliseconds = ElapsedMilliseconds;
        OldElapsedMilliseconds = 0;
        sw.Reset();
        sw.Start();
 
        System.Threading.Thread.Sleep(Sleep); 
         //-----------------Restart----------------End
      }
       
      //------------Must define some condition to break the loop here-----------Start

      if (lst.Count > 500)
      {
        Write();
        break;
      }
      //-------------Must define some condition to break the loop here-----------End
    }
  }

 
  private void Write()
  {
    System.IO.StreamWriter sw = new System.IO.StreamWriter("d:\\text.txt", true);
    foreach (DateTime dtStart in lst)
      sw.WriteLine(dtStart.ToString("HH:mm:ss.ffffff"));    sw.Close();
  }
}

Also that:

Most accurate timer in .NET?

High resolution timer

High resolution timer in C#

Microsecond and Millisecond C# Timer

Precision-Repeat-Action-On-Interval-Async-Method