Microsoft は 2007 年から .NET の並列処理拡張 (Parallel Extensions) に取り組んでいるが,それでも .NET 4.0 に実装完成が間に合わなかった機能が数多く残っている。“フレームワークのコアに含めるには,アプリケーション依存性が強すぎる” 機能もあったが,その他は単純にテストとユーザフィードバックの不足が理由だ。それについて Stephen Toub 氏は,
幸運なことに,これらのケースの大部分について .NET 4 が提供する並列化構造を使って機能を構築することができました。.NET 4 のタイプとメソッドのみで構成されたものもありますが,.NET 4 で提供される拡張ポイント (Extensibility Point) を活用したケースもいくつかあります。拡張ポイントは,フレームワークの持っていない機能を開発者自身がカスタマイズ機能として提供可能にすることを目的に,.NET 4 で提供されているものです。時間が経つにつれて,この種のコード資産も蓄積されてきました。そこで .NET 4 サンプルのひとつである ParallelExtensionsExtras プロジェクトを通じて,その大部分を公開することにしました。http://code.msdn.microsoft.com/ParExtSamples からダウンロードすることができます。
コードサンプルは広範な機能をカバーしている。主要なものから いくつか紹介しよう。
BlockingCollection ラッパ用の IProducerConsumerCollection 実装。このインターフェースは,いわゆる producer/consumer シナリオを提供するスレッドセーフなコレクションで使用されている。BlockingCollection 用の正確なセマンティクスに,アプリケーションの要求に依存する部分が大きいと判断されたため,.NET 4.0 には含まていなかったものだ。
シングルスレッドアパートメントが必要な COM コンポーネントを使用するためのものとして,StaTaskScheduler がある。その基本的な実装は,既定数の STA スレッドを起動してタスクの完了を待つ,という非常にシンプルなものだ。拡張実装の例として,スレッドローカルストレージ (thread-local storage)を使用して,各ワーカスレッドに対して COM オブジェクトのインスタンスを1つずつ生成する,という構成が紹介されている。
Reactive Extension フレームワークに関心を持つ向きに対しては,サブスクリプションをタスク結果にアタッチさせる Task.ToObservable 拡張メソッドがある。タスク完了前にサブスクリプションが停止した場合は,そのタスクがキャンセルされる。
かなり複雑なシナリオとしては ReductionVariable がある。1組の値のそれぞれに1インスタンス,1スレッドを割り当て,リダクション演算 (Reduction Operation)を行う,というものだ。スレッドローカルストレージをベースとしていて,ワーカスレッド間の同期処理を最小限に抑えることができるため,スケールアップ性がよい。リダクション演算が完了したら,それぞれの値を収集して最終結果を求める。