I've recently noticed very strange behaviour of ManualResetEvent
class in .NET framework. I am using C#, VS 2015, project's target is set to 4.5.2. Here is the full code:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace CSharpCOnsole
{
class Program
{
private static ManualResetEvent exit = new ManualResetEvent(false);
static void Main(string[] args)
{
var t = Task.Factory.StartNew(F);
Console.ReadKey();
exit.Set();
t.Wait();
exit.Close();
}
static void F()
{
var dtStopwatch = new Stopwatch();
uint ii = 0;
while (!exit.WaitOne(25)) {
dtStopwatch.Stop();
var dt = 1000.0 * dtStopwatch.ElapsedTicks / Stopwatch.Frequency;
dtStopwatch.Restart();
if (ii++ % 40 == 0) {
Console.WriteLine(dt.ToString("F3"));
}
}
}
}
}
I know that it may sound stupid, but here is what happens: if I restart my PC, run VS right after boot and run this program, i get the following output:
31.665
31.365
31.541
...
What is more, if i change 25
in !exit.WaitOne(25)
to any other number in range 16
to 31
, i get the same result: it waits 31
ms. If i pick any number in range 1
to 15
it waits exactly 16
ms. And so on, if i pick any nuber in range 32
to 47
it waits exactly 48
ms.
BUT: if I compile-and-run this code several times (about 10-30) or wait for some time (about 5-20 min after boot), it suddenly starts working fine! Yes, it sounds ridiculus, but it is what happens. It starts blocking the loop for the exact given time with 1 ms precision. And it keeps going until the next PC restart. I have tried this on two different PCs and got the same behaviour. Googling gave me absolutely nothing on this problem. If i run compiled EXE without VS, i get the same behaviour.