【发布时间】:2019-12-03 15:01:19
【问题描述】:
我有一个需要通过 UDP 发送音频数据包的应用程序。为了避免抖动,我想安排一个线程或任务每 20 毫秒执行一次此任务。伪代码如下所示:
while(true)
{
byte[] packet = GetNextPacket();
socket.Send(packet);
var waitUntill = DateTime.Now.AddMilliseconds(20);
while(DateTime.Now < waitUntill) { }
}
这工作正常,但它使用了 100% 的 CPU 内核。这当然是不可取的。我尝试过使用 Thread.Sleep 和 Thread.Yield 以及它们的任务等效项,但在所有情况下,我要么最终得到 100% 的负载,要么得到极度紧张的体验(这是意料之中的)。
在 C# 中没有办法在如此细粒度的级别上安排任务吗?我不需要 100% 的保证(Windows 不是实时操作系统),但大多数时候都可以使用。请注意,我并不担心 GC :)。
我可以调用任何 COM 代码来实现这一点,尽管我理想的解决方案是多平台的。我目前正在使用 dotnet core 3.0。
如果在 C# 中无法实现,那么如何在 C++ 等执行此类任务的语言中实现。
【问题讨论】:
-
在异步方法
await Task.Delay(20); -
jitter的问题主要来自网络拥塞。您最好尝试在接收端稍微缓冲它。另外,请了解 UDP 会丢失数据报,您需要考虑丢失的数据。
-
在这里使用异步回调将大大受益。它允许您将这些数据包信息与您的计算机执行的任何其他逻辑并行运行。
-
@Slothario 听起来不错! :D
-
@Slothario 您可以将您的评论转换为答案吗?因为它使用多媒体计时器就像一个魅力。不幸的是不是跨平台的,但我希望以后能解决这个问题。
标签: c# multithreading networking task scheduling