非同期コールバックで大量の処理をしても大丈夫ですか?
-
09-10-2019 - |
質問
.NETの非同期コールバックで大量の処理を行い、戻る前に複数秒間ホグすることは大丈夫ですか?それとも、重要なリソースのOS /ランタイムを奪っていますか?
たとえば、考慮してください TcpListener.BeginAcceptSocket
. 。私のコールバックは、呼び出すことから始まります EndAcceptSocket
, 、その後、データを受け取るのに時間を費やし、その後、ソケットを閉じて返品します。これはそれがどのように使用されるかどうか、または私は自分のスレッドで追加の処理を行うことを期待されていますか?
解決
はい、これは非同期ソケット(TCPクライアント、リスナーなど)が使用するために設計されている方法です。 End AYSNCメソッドを呼び出してから、必要な処理を行うことを常に確認する必要があります。 Endaccept()、Endend()、Endreceive()などを呼び出さないでください。メソッドは、メモリリークに潜在的に開かれたままにするため、従うのは常に良い習慣です。
使用されているスレッドは、自分で背景スレッドを手動でスプールし、数秒の「長期操作」にも使用されると考えられている場合と変わりません。私を信じてください、あなたはディスパッチまたはGUIスレッドで走るのにそれほど長い時間がかかるものを望んでいません。
私はサーバーへのCommucationにAsychronous Socketsを使用する90を超えるモバイルベースのシステムを持っています。それは優れた仕事をします:Webサービスよりもはるかに速い(すべてのWebプロトコルはとにかくソケットの上で実行されることを覚えておいてください)、エラーなどを簡単に検出します。等
私はサーバーコードで同じことをします(ミドルウェアやバックエンド通信の他のWCFと混合されています)。これは、使用した中で最もスケーラブルな通信です。 Googleを行う必要がありますが、このテクノロジーを使用してテストを公開した人がいて、わずか11スレッドのサーバーとの1,000の同時通信をサポートすることができました。悪くない。
MSからのサーバーの例: http://msdn.microsoft.com/en-us/library/fx6588te.aspx
MSからのクライアントの例: http://msdn.microsoft.com/en-us/library/bew39x2a.aspx
「完成」するにはこれら以上のものが必要ですが、これは始めるのに適した場所です。
他のヒント
aの実験を繰り返しました このトピックに関するCodeProjectの記事 また、.NET 4の結果は2003年に説明されたものと同様であることがわかりました。この記事は実際に問題のあるセクションの結果をリストしていなかったことに注意してください。
CodeProjectの記事からコードを再利用しました - これをダウンロードして、このテストを自分で実行するか、実験してください。
このテストでは、10個の並列スレッドを使用して、1秒でできる限り高くカウントしようとします。
10個の背景スレッドを使用します(つまり、 new Thread()
)
T0 = 4451756 T1 = 4215159 T2 = 5449189 T3 = 6244135 T4 = 3297895 T5 = 5302370 T6 = 5256763 T7 = 3779166 T8 = 6309599 T9 = 6236041 Total = 50542073
10個のThreadPoolワークアイテムを使用します
T0 = 23335890 T1 = 20998989 T2 = 22920781 T3 = 9802624 T4 = 0 T5 = 0 T6 = 0 T7 = 0 T8 = 0 T9 = 0 Total = 77058284
1秒のスライスの間に実際に実行された10個のうち4個のスレッドプールワークアイテムのみが発生していることに注意してください! これはクアッドコアCPUにあるため、コアごとに1つのスレッドでした。最初の4つが完了した後に実行された他のタスクと、1秒の割り当てられた1秒がすでに期限切れになっていたため、カウンターは増加しませんでした。
ここでの結論: 長いタスクがあれば、ThreadPoolは他のタスクをいくつか待っています! したがって、Threadpoolタスク(非同期完了ハンドラーなど)で長い処理を行うことを強くお勧めします。それ以外の場合は、データ処理がCPUを抱えている場合、または一部のタスクだけが多くの処理を行う場合、非常に不安定なパフォーマンスがある場合、より重要な非同期コールを完了することを維持する場合があります。
記事からカスタムスレッドプールの実装を使用します
T0 = 7175934 T1 = 6983639 T2 = 5306292 T3 = 5078502 T4 = 3279956 T5 = 8116320 T6 = 3262403 T7 = 7678457 T8 = 8946761 T9 = 8500619 Total = 64328883