TaskScheduler クラス

Last Updated 2011/09/21


.NET Framework における並列処理は、タスクスケジューラを介して、タスクと実際にタスクを実行するスレッドと間の調整をします。調整とはタスクをどのスレッドに割り当てるか、あるいはタスクを実行する順番を管理することです。パソコンで動作可能なスレッドは 少なくとも CPU のコア数の分はあるわけですが、それより多いスレッドの要求があればタスクスケジューラが調整します。

タスクスケジューラは内部的にはスレッドプールを使います。.NET Framework 4.0 のスレッドプールは並列処理を可能にするために、それまでのものとは大幅に変更されました。つまり、アプリケーション開発者はスレッドを直接操作するのではなく、タスクスケジューラという抽象的な仕組みを使って操作することになりました。こうすることで、.NET Framework の将来のバージョンにおいて内部的な大幅な変更があってもアプリケーションのコードの変更を避けるメリットがあります。


デフォルトのタスクスケジューラ

アプリケーションには自動的にスレッドプールが割り当てられますが、スレッドプールはデフォルトのタスクスケジューラを持ちます。タスクスケジューラが内部的に何をやっているかは上記で説明したようにブラックボックスになっていますので、解説のしようがありません。

さて、コンソールアプリケーションには ThreadPool スレッドしかありませんので、デフォルトのタスクスケジューラは一つだけです。一方、UI アプリケーションには ThreadPool スレッド用と UI スレッド用との 2 つのデフォルトのタスクスケジューラがあります。コンソールアプリケーションの場合は迷いはないと思いますが、UI スレッド用のタスクスケジューラについては次の項で説明します。


UI アプリケーション用デフォルトのタスクスケジューラ

UI コントロールはそれを作成したスレッドからでしかアクセスできません。そのためには UI スレッドに割り当てられたタスクスクジューラを取得する必要があります。それを実現する機能は、TaskScheduler クラスの static な FromCurrentSynchronizationContext メソッドが提供します。次のコードは UI スレッドのデフォルトのタスクスケジューラを取得するものです。

  var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

ちなみに、コンソールアプリケーションでこのメソッドを呼び出すと、「現在の SynchronizationContext を TaskScheduler として使用することはできません。」エラーになります。

なお、並列処理における UI コントロールの操作については、並列処理における UI コントロールの操作のページを参照してください。


カスタムタスクスケジューラ

デフォルトのタスクスケジューラでは不満の場合、TaskScheduler クラスから派生するクラスを作成し、タスクスケジューラをカスタム化することができます。私は興味がありませんので、公開されているものを紹介して、解説にかえます。次のサイトから ParalleleProgrammingSamples.zip をダウンロードしてください。

Samples for Parallel Programming with the .NET Framework

ファイルを解凍すると、ParallelExtensionsExtras\TaskSchedulers ディレクトリの中にカスタムタスクスケジューラのコード例が入っています。

−以上−