70

少なくとも.NET4.0のリリース以来、Microsoftは並列および非同期プログラミングのサポートに多大な努力を払ってきたようであり、これに関連する多くのAPIとライブラリが出現したようです。特に、最近は次のような派手な名前がどこでも絶えず言及されています。

  • リアクティブフレームワーク、
  • PLINQ(Parallel LINQ)、
  • TPL(タスク並列ライブラリ)と
  • 並列拡張。

現在、これらはすべてMicrosoft製品のようであり、.NETの非同期または並列プログラミングシナリオを対象としているようです。しかし、それらのそれぞれが実際に何であるか、そしてそれらが互いにどのように関連しているかは完全には明らかではありません。いくつかは実際には同じものかもしれません。

一言で言えば、誰もが何が何であるかについて記録を立てることができますか?

4

2 に答える 2

98

PLINQ(Parallel Linq)は、通常のLinqクエリを記述して並列実行するための新しい方法です。つまり、Frameworkは複数のスレッド間でクエリを自動的に実行し、より高速に終了します(つまり、複数のCPUコアを使用します)。 )。

たとえば、文字列がたくさんあり、文字「A」で始まるすべての文字列を取得したいとします。次のようにクエリを記述できます。

var words = new[] { "Apple", "Banana", "Coconut", "Anvil" };
var myWords = words.Select(s => s.StartsWith("A"));

そして、これはうまくいきます。ただし、検索する単語が50,000語ある場合は、各テストが独立しているという事実を利用して、これを複数のコアに分割することをお勧めします。

var myWords = words.AsParallel().Select(s => s.StartsWith("A"));

通常のクエリを複数のコアで実行される並列クエリに変換するために必要なのはこれだけです。かなりきちんと。


TPL(タスク並列ライブラリ)はPLINQを補完するものであり、これらが一緒になって並列拡張機能を構成します。PLINQは主に副作用のない機能的なプログラミングスタイルに基づいていますが、副作用はまさにTPLの目的です。単に並行して検索/選択するのではなく、実際に並行して作業を行いたい場合は、TPLを使用します。

TPLは基本的に、、、およびのParallelオーバーロードを公開するクラスです。 のタスクをキューに入れるのと少し似ていますが、使用するのが少し簡単です。IMO、より興味深いビットはとです。たとえば、圧縮したいファイルがたくさんあるとしましょう。通常のシーケンシャルバージョンを作成できます。ForForeachInvokeInvokeThreadPoolForForeach

string[] fileNames = (...);
foreach (string fileName in fileNames)
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
}

この場合も、この圧縮の各反復は、他の反復から完全に独立しています。それらのいくつかを一度に実行することで、これをスピードアップできます。

Parallel.ForEach(fileNames, fileName =>
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
});

繰り返しになりますが、この操作を並列化するために必要なのはこれだけです。これで、メソッド(またはメソッドと呼ぶことにしたもの)を実行するCompressFilesと、複数のCPUコアが使用され、おそらく半分または1/4の時間で終了します。

ThreadPoolすべてをチャックするだけでなく、これが実際に同期して実行されることの利点があります。ThreadPool代わりに(または単なるインスタンス)を使用Threadした場合、すべてのタスクがいつ終了したかを確認する方法を考え出す必要があります。これはそれほど複雑ではありませんが、多くの人が傾向があるものです。失敗するか、少なくとも問題が発生します。クラスを使用するときは、Parallel実際にそれについて考える必要はありません。マルチスレッドの側面はあなたから隠されており、すべて舞台裏で処理されます。


Reactive Extensions(Rx)は、実際にはまったく別の獣です。これは、イベント処理についての別の考え方です。これについてカバーする資料は本当にたくさんありますが、長い話を短くするために、イベントハンドラーをイベントに接続する代わりに、Rxではイベントのシーケンスを...まあ、シーケンス(IEnumerable<T>)として扱うことができます。イベントをランダムに非同期で発生させるのではなく、反復的に処理することができます。特定の順序で発生する一連のイベントを検出するには、常に状態を保存し続ける必要があります。

私が見つけたRxの最もクールな例の1つはここにあります。「LinqtoIObservable」セクションにスキップして、ドラッグアンドドロップハンドラーを実装します。これは通常、WPFでは面倒ですが、わずか4行のコードで実行できます。Rxは、通常のイベントハンドラーでは実際には得られないイベントの構成を提供します。また、このようなコードスニペットは、どこにでも配置できる動作クラスにリファクタリングするのも簡単です。


以上です。これらは、.NET4.0で利用できるより優れた機能の一部です。もちろん、他にもいくつかありますが、これらはあなたが尋ねたものでした!

于 2010-01-30T03:31:57.640 に答える
31

アーロノートの答えは好きですが、RxとTPLは異なる問題を解決すると思います。TPLチームが追加したものの一部は、スレッドプリミティブと、ThreadPoolのようなランタイムのビルディングブロックに対する大幅な機能強化です。そして、リストするものはすべて、これらのプリミティブとランタイム機能の上に構築されています。

しかし、TPLとRxは2つの異なる問題を解決します。TPLは、プログラムまたはアルゴリズムが「プル&キューイング」の場合に最適に機能します。Rxは、プログラムまたはアルゴリズムがストリームからのデータに「反応」する必要がある場合(マウス入力など)、またはWCFなどのエンドポイントから関連メッセージのストリームを受信する場合に優れています。

ファイルシステムのように機能したり、コレクションを反復処理したり、組織図のように階層をたどったりするには、TPLの「作業単位」の概念が必要です。いずれの場合も、プログラマーは全体的な作業量について推論でき、作業は特定のサイズのチャンクに分割でき(タスク)、階層全体で計算を行う場合は、タスクを「チェーン」できます。 。そのため、特定の種類の作業はTPLの「タスク階層」モデルに役立ち、キャンセルなどの配管の機能強化の恩恵を受けます(CancellationTokenSourceのチャンネル9ビデオを参照)。TPLには、ほぼリアルタイムのデータ処理などの特殊なドメイン用のノブもたくさんあります。

Rxは、ほとんどの開発者が最終的に使用する必要があるものになります。これは、WPFアプリケーションが外部データ(IMクライアントへのIMメッセージのストリーム)や外部入力(Aaronaughtからリンクされたマウスドラッグの例など)などの外部メッセージに「反応」する方法です。内部では、RxはTPL / BCLのスレッドプリミティブ、TPL / BCLのスレッドセーフコレクション、およびThreadPoolなどのランタイムオブジェクトを使用します。私の考えでは、Rxはあなたの意図を表現するためのプログラミングの「最高レベル」です。

平均的な開発者が、Rxで表現できる一連の意図に頭を悩ませることができるかどうかはまだわかりません。:)

しかし、今後数年間は、TPLとRxが、LINQ-to-SQLとEntityFrameworkのような次の議論になると思います。同じドメインには2つの種類のAPIがあり、さまざまなシナリオに特化していますが、多くの点で重複しています。ただし、TPLとRxの場合、実際にはお互いを認識しており、アプリケーションを構成して両方のフレームワークを一緒に使用するための組み込みアダプターがあります(PLINQループからの結果をIObservable Rxストリームにフィードするなど)。並列プログラミングを行ったことがない人にとっては、スピードを上げるための学習がたくさんあります。

更新:過去6か月間(最初の回答から18か月間)、通常の作業でTPLとRxNetの両方を使用しています。中間層のWCFサービス(エンタープライズLOBサービス)でのTPLおよび/またはRxNetの選択についての私の考え:http: //yzorgsoft.blogspot.com/2011/09/middle-tier-tpl-andor-rxnet.html

于 2010-02-02T22:31:59.310 に答える