2

私は Objective-C のバックグラウンドを持っており、Grand Central Dispatch または NSOperations を使用してこの問題をかなり簡単に解決していました。残念ながら、C# でこの問題を構造化しようとすると、その考え方にとらわれていると思います。

高レベルのタスクがあり、それぞれに並行して発生する可能性のある複数の部分があります。これらの各部分は、パイプラインでいくつかの段階を経る必要があります。このパイプラインを構築する必要がありますが、高レベルのタスクがいつ完了するかを把握し、コールバックを実行します。

GCD では、パーツを実行するためのキューを作成し、それぞれがプロセスの次のパーツに連鎖します。これらのパーツはすべて、それらが含まれていた高レベルのタスクに基づいてグループ化されるため、最後にコールバックをトリガーできます。

これがC#でどのように機能するかを理解するのに苦労しています。私は主に Task Parallel Library を研究してきましたが、使用するものに特に好みはありません。これまでに遭遇した問題の 1 つは、TPL パイプラインで処理を終了した場合にのみ完了コールバックが可能であるように見えることですが、発生しないタスクが複数あるためです。

概要レベルで、この問題をどのように構成するのが最適でしょうか? 同時実行性を提供する Rx を使用してシステムを作成する方がよいのではないでしょうか?

4

3 に答える 3

1

複数のタスクがあるために完了コールバックがオプションではないという意味がよくわかりません。各タスクのデータフロー ネットワークを構築することは、それらの完了が個別にトリガーされることを意味します。

毎回ネットワークを再構築することによるオーバーヘッドを避けたいと思いますか? その場合、最後に一種のパススルー ブロックを追加することができます。これは、与えられた入力を返し、必要なコールバックを呼び出します。したがって、ネットワークによって生成される各出力に対して、コールバックが呼び出されます。さらに一歩進めたい場合は、代わりにメッセージを別のブロックに投稿し、コールバックを並行して呼び出すことができます。

あるいは、パイプラインが十分に単純で、追加のバッファリングなどを必要としない場合は、単純な TPL タスクでそれを行うことができますか? このようなもの:

public async Task<string> HighLevelTask(string input1, string input2, Action completed) {
    Task<string[]> parts = Task.WhenAll(Part1(input1), Part2(input2));
    string[] results = await parts;
    completed();
    return string.Join(",", results);
}
public async Task<string> Part1(string input) {
    var result1 = await Stage1(input);
    var result2 = await Stage2(result1);
    return result2;
}
于 2013-07-28T08:30:41.440 に答える
1

私には、TPL Dataflow が正しい方法のように思えます。Rx は Dataflow ができることは何でも実行できますが、実際のデータフロー (パイプラインを含む) に対して Dataflow の構文がよりクリーンである一方で、イベント/時間管理に非常に優れています。

Dataflow にはアイテムごとの完了通知が組み込まれていないことは間違いありません。ActionBlockたとえば、すべての項目の最後にan を付けて、自分で追加する必要があります。

私のAsyncEx ライブラリが役に立つかもしれません。特に、私は非同期調整プリミティブAsyncCountdownEventをいくつか持っています。これには、必要なもののように聞こえるものも含まれます。

于 2013-07-28T11:53:59.803 に答える