非同期処理、マルチスレッド(ThreadPool)
<ThreadPoolクラスの基本>
前回Threadクラスを用いた非同期処理を説明しましたが、スレッドの新規作成は思っている以上にコストがかかります。スレッドは生成だけではなく破棄される時もコストがかかるので、頻繁に使用すると処理がとても重くなってしまいます。
あまりThreadを増やし過ぎたり同時実行が多すぎると、シングルスレッドの時より処理が遅くなってしまう事も・・・。
それを改善した手法がThreadPoolクラスです。プールはプログラミング用語で良く出てきますが、その名の通り「Threadの置き場」という感じでしょうか。あらかじめ生成したスレッドを破棄せず保留しておき、必要になったら使いまわすといった感じ(ワーカープロセスみたいな)。効率よく処理を実行することが可能になります。
public static void Main() { System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(HeavyProc)); for (int i = 0; i <= 5; ++i) { System.Threading.Thread.Sleep(1000); Console.WriteLine("Piyo"); } } private void HeavyProc(object obj) { for (int i = 0; i <= 5; ++i) { System.Threading.Thread.Sleep(1000); Console.WriteLine("Hoge"); } }
Public Shared Sub Main() System.Threading.ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback(AddressOf HeavyProc)) For i As Integer = 0 To 5 System.Threading.Thread.Sleep(1000) Console.WriteLine("Piyo") Next End Sub Private Sub HeavyProc(ByVal obj As Object) For i As Integer = 0 To 5 System.Threading.Thread.Sleep(1000) Console.WriteLine("Hoge") Next End Sub
結果はThreadクラスと同様です。
Piyo Hoge Piyo Hoge Piyo Hoge Piyo Hoge Piyo Hoge Piyo Hoge
なお、ThreadPoolクラスはバックグラウンドで処理されます。
ThreadPoolクラスQueueUserWorkItemメソッドによりThreadPoolキューにメソッド(ここではHeavyProc)が追加されます。追加されたキューは先入れ先出し(FIFO)で効率よく処理されます。
因みに、.NET Framework4よりスレッドプールの再構築・再設計が行われ、従来に比べてより効率よく処理されるようになっています。