在.NET应用程序中需要微秒延迟以限制UDP多播传输速率

n9vozmp4  于 2023-01-22  发布在  .NET
关注(0)|答案(6)|浏览(133)

我正在用C#编写一个UDP多播客户端/服务器对,我需要一个50-100微秒的延迟来调节服务器的传输速率。这有助于避免大量的数据包丢失,也有助于避免磁盘I/O绑定的客户端过载。请不要建议使用Thread.Sleep或Thread. SpinWait。我不会问我是否需要这两个。
我的第一个想法是使用某种高性能计数器,并执行一个简单的while()循环来检查运行时间,但我希望避免这样做,因为这样做感觉很笨拙。
跨平台解决方案的加分,即不是Windows特定的。提前感谢,伙计们!

v6ylcynt

v6ylcynt1#

非常短的睡眠时间通常最好通过CPU自旋循环(如您所描述的那种)来实现。您通常希望避免使用高精度计时器调用,因为它们本身会占用时间并扭曲结果。我不会太担心CPU在如此短的等待时间内与服务器挂钩。
我将把行为封装在一个类中,如下所示:

  • 创建一个类,它的静态构造函数运行一个自旋循环数百万次迭代,并捕获它所花费的时间,这让你知道一个循环周期在底层硬件上需要多长时间。
  • 计算一个uS/iteration值,可用于计算任意休眠时间。
  • 当要求休眠一段特定时间时,将休眠的uS除以先前计算的uS/迭代值,以确定要执行多少次循环迭代。
  • 使用while循环进行旋转,直到经过估计的时间。
ttygqcqt

ttygqcqt2#

我将使用stopwatch,但需要一个循环
读取this以向秒表添加更多扩展,如ElapsedMicroseconds
或者类似的东西也可以
系统.诊断.秒表.IsHighResolution必须为真

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();
       

    }
s1ag04yj

s1ag04yj3#

当我的多播应用程序需要更高的精度时,我就遇到过这样的需求。
我发现最好的解决方案是this example中的多媒体定时器。
我已经使用了这个实现并添加了TPL异步调用。您应该可以查看我的SimpleMulticastAnalyzer项目以获得更多信息。

yftpprvb

yftpprvb4#

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);
        }
    }
ymzxtsji

ymzxtsji5#

我不鼓励使用spin循环,因为它会消耗和创建阻塞线程。thread.sleep更好,它在睡眠期间不使用处理器资源,它只是分割时间。尝试一下,你会从任务管理器看到spin循环是如何使CPU使用率激增的。

hpcdzsge

hpcdzsge6#

你看过multimedia timers吗?你可能会在某处找到一个 Package API调用的.NET库。

相关问题