私は現在、私が書いたマネージ C# ネットワーク ライブラリをテストしていますが、時折問題に遭遇しました。この問題は、おそらくすべての送信操作の 1% で、networkstream.write() で非常に一貫した (常に 30 ミリ秒以内) 5000 ミリ秒のブロックとして現れます。これはテスト環境で、毎回まったく同じパケット サイズ (2MB) を使用して、すべてローカルで実行されています。クライアント側では、接続されたネットワーク ストリームに次の内容を継続的に書き込みます。
tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length);
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length);
サーバー側では、データを待機する非同期読み取りを使用します。データが表示されたら、すべてのデータが受信されるまで、tcpClientNetworkStream.DataAvailable に対して while ループを使用します。
バッファがいっぱいの場合、 networkstream.write() がブロックされる可能性があることは認識していますが、これが問題である場合、サーバー側でバッファをクリアするより迅速な方法は考えられません (送信および受信バッファ サイズはデフォルトで 8192 バイトです)。 . ブロックが非常に一貫しているという事実は、非常に奇妙に思えます。私が最初に考えたのは、おそらく何らかの形の Thread.Sleep でしたが、プロジェクト全体を検索しても何も表示されませんでした。誰かがこの問題に光を当てるのを助けることができれば、それは大歓迎です.
マルク
追加する編集:問題を解決するように見えるハックは次のとおりです(BlockCopyによる関連するパフォーマンスヒットがありますが):
byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length];
Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length);
Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length);
tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length);
add2 への編集: また、2 つの非同期書き込みを使用して、2 つの間のスレッド シグナルを使用して問題を再現しました。現時点で私が持っている唯一の解決策は、上記の編集のように単一の書き込み操作です。
add3 への編集: OK、別の可能な修正が続きます。連続した書き込みが時折「ブロック」する理由を知りたいと思っています。
BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream);
sendStream.Write(bytesToSend, 0, bytesToSend.Length);
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length);
sendStream.Flush();
add4 への編集: 「add3 への編集」の解決策をさらに広範囲にテストした後、問題は解消されず、発生が送信の約 0.1% に減少するだけです。はるかに優れていますが、解決には程遠いです。PaulF が提案したように、次に非同期読み取りをブロック読み取りに置き換えて、それがソートされるかどうかを確認します。