我遇到了 C# 启动时间慢导致 UDP 数据包最初丢弃的问题。下面是我为减轻这种启动延迟所做的工作。我基本上在前两个数据包传输之间额外等待了 10 毫秒。这至少在我的机器上修复了初始下降。我担心的是较慢的机器可能需要比这更长的延迟。
private void FlushPacketsToNetwork()
{
MemoryStream packetStream = new MemoryStream();
while (packetQ.Count != 0)
{
byte[] packetBytes = packetQ.Dequeue().ToArray();
packetStream.Write(packetBytes, 0, packetBytes.Length);
}
byte[] txArray = packetStream.ToArray();
udpSocket.Send(txArray);
txCount++;
ExecuteStartupDelay();
}
// socket takes too long to transmit unless I give it some time to "warm up"
private void ExecuteStartupDelay()
{
if (txCount < 3)
{
timer.SpinWait(10e-3);
}
}
所以,我想知道有没有更好的方法让 C# 完全加载它的所有依赖项?我真的不介意完全加载是否需要几秒钟。我只是不想在 C# 准备好全速之前进行任何高带宽传输。
其他相关细节
这是一个控制台应用程序,网络传输是从一个单独的线程运行的,主线程只是等待按键来终止网络传输。
在该Program.Main
方法中,我尝试通过使用合理的最高优先级从我的应用程序中获得最高性能:
public static void Main(string[] args)
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
...
Thread workerThread = new Thread(new ThreadStart(worker.Run));
workerThread.Priority = ThreadPriority.Highest;
workerThread.Start();
...
Console.WriteLine("Press any key to stop the stream...");
WaitForKeyPress();
worker.RequestStop = true;
workerThread.Join();
此外,我当前使用的套接字设置如下所示:
udpSocket = new Socket(targetEndPoint.Address.AddressFamily,
SocketType.Dgram,
ProtocolType.Udp);
udpSocket.Ttl = ttl;
udpSocket.SendBufferSize = 1024 * 1024;
udpSocket.Blocking = true;
udpSocket.Connect(targetEndPoint);
默认值SendBufferSize
是 8192,所以我继续将它移到了兆字节,但这个设置似乎对一开始丢弃的数据包没有任何影响。