DotNet alternative (MONO-http://www.go-mono.com/mono-downloads/download.html) handles the short timer condition properly (down to ~12 ms firing time) Yet, DotNet appears to take longer then expected and "Misses". So, which behavior is correct? Does mono properly track its event firing?, is it fudging its number with an incorrect stopwatch? or does DotNet have a "lazy" event timer? With my testing, clearly, it is not a underlying windows issue.
.NET 200ms+ Interval minimum
Mono 12ms+ Interval minimum
This inquiry in similar to this: Timer takes 10 ms more than interval.
However consider the code:
In .NET missed events will slowly tick up:
Total Runtime/Interval - Actual Events = Missed Events
Code:
class Program
{
const int Interval = 60; //ms Event fireing
Stopwatch TotalRunTime = new Stopwatch();//Full runtime.
Stopwatch Calctime = new Stopwatch(); //Used to load up the Event to 66 percent
System.Timers.Timer TIMER; //Fireing Event handler.
int TotalCycles = 0; //Number of times the event is fired.
int Calcs_per_cycle = 100; // Number of calcs per Event.
static void Main(string[] args)
{
Program P = new Program();
P.MainLoop();
}
void MainLoop()
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
TIMER = new Timers.Timer();
TIMER.Interval = Interval;
TIMER.Elapsed += new ElapsedEventHandler(MS_Calc);
TIMER.AutoReset = true;
TIMER.Enabled = true; //Start Event Timer
TotalRunTime.Start(); //Start Total Time Stopwatch;
while (true)
{
Thread.Sleep(Interval * 5);
Console.Clear();
PrintAtPos(2, "Missed Events " + (((TotalRunTime.ElapsedMilliseconds / Interval) - TotalCycles).ToString()));
}
}
public void MS_Calc(object source, System.Timers.ElapsedEventArgs E)// public void MS_Calc(object source, ElapsedEventArgs E)
{
TotalCycles++;
Calctime.Start();
for (int i = 0; i < Calcs_per_cycle; i++)
{
int A = 2;
int B = 2;
int c = A + B;
}
PrintAtPos(1, "Garbge Collections G1: " + GC.CollectionCount(0) + " G2: " + GC.CollectionCount(1) + " G3: " + GC.CollectionCount(2) + " ");
Calctime.Stop();
if (Interval * 0.667 > Calctime.ElapsedMilliseconds) //only fill the even timer 2/3s
//full to make sure we finish before the next event
{
Calcs_per_cycle = (int)(Calcs_per_cycle * 1.035);
}
Calctime.Reset();
PrintAtPos(0, "Calc Time : " + (DateTime.Now - E.SignalTime).Milliseconds + " Calcs/Cycle: " + Calcs_per_cycle);
}
private static void PrintAtPos(int Vertical_Pos, string Entry)
{
Console.SetCursorPosition(0, Vertical_Pos);
Console.Write(Entry);
}
}