.NET の非同期コールバックで重い処理を行って、戻る前に数秒間それらを占有しても問題ありませんか? それとも、OS / ランタイムから重要なリソースを奪っていますか?
たとえば、 を考えてみましょうTcpListener.BeginAcceptSocket
。私のコールバックは を呼び出すことから始まりEndAcceptSocket
、しばらくデータを受信してからソケットを閉じて戻ります。これは意図された使用方法ですか、それとも自分のスレッドで余分な処理を行う必要がありますか?
.NET の非同期コールバックで重い処理を行って、戻る前に数秒間それらを占有しても問題ありませんか? それとも、OS / ランタイムから重要なリソースを奪っていますか?
たとえば、 を考えてみましょうTcpListener.BeginAcceptSocket
。私のコールバックは を呼び出すことから始まりEndAcceptSocket
、しばらくデータを受信してからソケットを閉じて戻ります。これは意図された使用方法ですか、それとも自分のスレッドで余分な処理を行う必要がありますか?
はい、これが非同期ソケット (Tcp クライアント、リスナーなど) を使用するために設計された方法です。必ず end aysnc メソッドを呼び出してから、必要な処理を行うようにしてください。EndAccept()、EndSEnd()、EndReceive() などのメソッドを呼び出さないと、メモリ リークが発生する可能性があるため、常に従うことをお勧めします。
使用されるスレッドは、バックグラウンド スレッドを自分で手動でスプールした場合と同じであり、実際には、数秒の「長時間操作」にも使用されるように設計されています。私を信じてください、ディスパッチまたは GUI スレッドで実行するのにそれほど時間がかかるものは必要ありません。
サーバーとの通信に非同期ソケットを使用する 90 以上のモバイル ベースのシステムがあり、Web サービスよりもはるかに高速であり (すべての Web プロトコルがソケット上で実行されることを思い出してください)、エラーの検出が容易です。等
サーバー コード (ミドルウェアおよびバックエンド通信用の他の WCF と混合) で同じことを行います。これは、使用した中で最もスケーラブルな通信です。Google で検索する必要がありますが、このテクノロジを使用したテストを公開した人がいて、サーバーへの 1,000 の同時通信をわずか 11 スレッドでサポートできました。悪くない。
MS のサーバーの例: http://msdn.microsoft.com/en-us/library/fx6588te.aspx
MS からのクライアントの例: http://msdn.microsoft.com/en-us/library/bew39x2a.aspx
それを「完璧」にするにはこれら以上のことが必要ですが、ここから始めるのが良いでしょう。
このトピックに関する 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 合計 = 50542073
10 個の ThreadPool ワークアイテムを使用する
T0 = 23335890 T1 = 20998989 T2 = 22920781 T3 = 9802624 T4 = 0 T5 = 0 T6 = 0 T7 = 0 T8 = 0 T9 = 0 合計 = 77058284
1 秒のタイム スライス中に実際に実行されたスレッド プール作業項目は 10 個のうち 4 個だけであることに注意してください。これはクアッドコア CPU 上にあるため、コアあたり 1 スレッドでした。最初の 4 つのタスクが完了した後に実行された他のタスクは、割り当てられた 1 秒がすでに期限切れになっているため、カウンターをインクリメントしませんでした。
ここでの結論:長いタスクでは、ThreadPool はいくつかのタスクを他のタスクの後ろに待たせます! したがって、ThreadPool タスク (非同期完了ハンドラーなど) で長い処理を実行しないことを強くお勧めします。そうしないと、データ処理が CPU を占有している場合に、より重要な非同期呼び出しが完了しなくなる可能性があります。または、一部のタスクだけが多くの処理を行う場合、パフォーマンスが非常に不安定になる可能性があります。
記事のカスタム ThreadPool 実装の使用
T0 = 7175934 T1 = 6983639 T2 = 5306292 T3 = 5078502 T4 = 3279956 T5 = 8116320 T6 = 3262403 T7 = 7678457 T8 = 8946761 T9 = 8500619 合計 = 64328883