5

C# を使用して真の関数パイプラインを作成する方法は? 私は次のようなアイデアを得ましたが、それは真のパイプラインではありません

public static IEnumerable<T> ForEachPipeline<T>(this IEnumerable<T> source, params Func<T, T>[] pipeline)
{
 foreach (var element in source) {
  yield return ExecutePipeline(element, pipeline);
 }
}

private static T ExecutePipeline<T>(T element, IEnumerable<Func<T, T>> jobs)
{
 var arg = element;
 T result = default(T);
 foreach (var job in jobs) {
  result = job.Invoke(arg);
  arg = result;
 }
 return result;
}

上記のコードでは、 の各要素はIEnumerable<T>、前の要素がすべての関数の実行を終了した後 (つまり、パイプラインを終了した後) にのみパイプラインに入ることができますが、定義によれば、 if の実行がelement1終了して実行がfunc1開始func2されると、その時までに実行element2が開始されfunc1、このようにして、パイプライン内の継続的なデータの流れを維持します。

この種のシナリオは C# で実装できますか? 可能であれば、サンプルコードを教えてください。

4

3 に答える 3

0

コメントから:スレッドが導入されない限り、単一の実行コンテキストしかありません (単一スレッドを使用した代替アプローチは、各ステップで遅延のない結果を構築するだけです)。スレッドでは、各ステージは「ポンプ」を介してメッセージを渡す単なる FIFO キューです。スレッド (実際には同時実行性) も複雑さを大幅に増加させます。おそらく .NET4 の「並列」メソッドを参照してください。

「簡単な」方法は、 Parallel.ForEachを使用して N 個の「開始」を構成することです。計算に副作用がないことを保証できる場合に限ります。

編集:コメントを参照してください。

于 2010-11-13T17:38:30.657 に答える
0

この動作は、真のパイプラインよりも効率的です。パイプライン処理は、操作を並列で実行できる場合にのみ意味がありますが、これらのジョブはすべて 1 つの CPU スレッドを共有しているため、パイプライン処理されたとしても順次実行する必要があります。

パフォーマンスが向上しないことを理解していてもパイプラインを使用したい場合は、コメントを残してください。その方法を説明しますが、最初に何を求めているのかを確認したいと思います。

于 2010-11-13T17:31:26.820 に答える
0

仕事が処理されるかどうかに関係なく、主要なアーキテクチャ要素が 1 つ欠けていると思います。パイプラインは、従来の GoF の責任の連鎖に非常に似ています。GoF の本をお持ちでない場合は、こちらをご覧ください。

http://www.dofactory.com/Patterns/PatternChain.aspx#_self1

「T」を、ジョブが処理されたかどうかをパイプラインに伝えるインターフェイスに制限する必要があると思います(「where」ステートメントを使用します)。

また、PLINQ フレームワークも調べてください。私はそれがあなたが探しているものではないことを知っています(そこでは、複数のジョブを並行して実行することを目的としています)が、いくつかの良いアイデアが得られるかもしれません.

于 2010-11-13T17:37:55.963 に答える