Need microsecond delay in .NET app for throttling UDP multicast transmission rate

被刻印的时光 ゝ 提交于 2019-11-29 00:10:10

I would use stopwatch but would need a loop

read this to add more extension to the stopwatch, like ElapsedMicroseconds

or something like this might work too

System.Diagnostics.Stopwatch.IsHighResolution MUST be true

    static void Main(string[] args)
    {
        Stopwatch sw;
        sw = Stopwatch.StartNew();
        int i = 0;

        while (sw.ElapsedMilliseconds <= 5000)
        {
            if (sw.Elapsed.Ticks % 100 == 0)
            { i++; /* do something*/ }
        }
        sw.Stop();


    }

Very short sleep times are generally best achieved by a CPU spin loop (like the kind you describe). You generally want to avoid using the high-precision timer calls as they can themselves take up time and skew the results. I wouldn't worry too much about CPU pegging on the server for such short wait times.

I would encapsulate the behavior in a class, as follows:

  • Create a class whose static constructor runs a spin loop for several million iterations and captures how long it takes. This gives you an idea of how long a single loop cycle would take on the underlying hardware.
  • Compute a uS/iteration value that you can use to compute arbitrary sleep times.
  • When asked to sleep for a particular period of time, divide uS to sleep by the uS/iteration value previously computed to identify how many loop iterations to perform.
  • Spin using a while loop until the estimated time elapses.

I've experienced with such requirement when I needed more precision with my multicast application.

I've found that the best solution resides with the MultiMedia timers as seen in this example.

I've used this implementation and added TPL async invoke to it. You should see my SimpleMulticastAnalyzer project for more information.

    static void udelay(long us)
    {
        var sw = System.Diagnostics.Stopwatch.StartNew();
        long v = (us * System.Diagnostics.Stopwatch.Frequency )/ 1000000;
        while (sw.ElapsedTicks < v)
        {
        }
    }
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine("" + i + " " + DateTime.Now.Second + "." + DateTime.Now.Millisecond);
            udelay(1000000);
        }
    }

Have you looked at multimedia timers? You could probably find a .NET library somewhere that wraps the API calls somewhere.

I would discourage using spin loop as it consumes and creates blocking thread. thread.sleep is better, it doesn't use processor resource during sleep, it just slice the time. Try it, and you'll see from task manager how the CPU usage spike with the spin loop.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!