.net async ioは応答ハンドラーでスリープを呼び出すことに関連付けられています
-
25-10-2019 - |
質問
Asyncメソッドを使用してこのようなソケットのデータを受信するコード(サーバー上)があります。
asyncRes = connectionSocket.BeginReceive(receiveBuffer, 0, RECEIVING_BUFFER_SIZE,
SocketFlags.None, out error, new AsyncCallback(ReceiveDataDone), null);
ソケットのハンドラー(受信者)には、他のことを待つためにthread.sleep(x)が使用される場合があります(実際には疑わしい実装)。これは疑わしいデザインであることは知っていますが、そのような種類のコードを作成すると、受信者が呼ばれているサーバーの他の保留中のソケットのために、アプリケーションで作成されたスレッドの爆発を説明できるのではないかと思います。 (サーバーによって多くの接続が処理されると、作成されたスレッドの数が比fig的に爆発します)。どうやっているのだろうか BeginReceive
.NETソケットの方法では、私が見る膨大な数のスレッドを説明できます。
解決
APMコールバックでブロッキングアクションを実行しないでください。これらはスレッドプールで実行されます。 Threadpoolは、短命のタスクの呼び出しのために設計されています。ブロック(または実行するのに長い時間がかかる)場合、(有限数の)スレッドを縛り付け、スレッドプールの飢vを引き起こしています。 ThreadPoolは余分なスレッドを簡単にスピンアップしないため(実際、余分なスレッドを起動するのは非常に遅いため)、ThreadPoolが新しいスレッドをスピンアップできる速さを制御するタイミングをボトルネックしています。
別の質問に答えたにもかかわらず、私がしばらく前に提供したこの答えは、同じ問題を説明しています。
他のヒント
使用しないでください Thread.sleep
スレッドプールスレッドで待つために、これによりスレッドがブロックされ、ブロックされている間、それ以上の作業を受け入れません。
使用できます タイマーコールバック このようなユースケースの場合。それは ThreadPool
その間に待機スレッドの他の作業をスケジュールします。