C# の起動時間が遅いため、UDP パケットが最初にドロップするという問題が発生しました。以下は、この起動遅延を軽減するために行ったことです。基本的に、最初の 2 つのパケット送信の間にさらに 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 なので、思い切って 1 メガバイトまで上げてみましたが、この設定は最初はドロップされたパケットに影響を与えていないようでした。