11

私は、Microsoft チームの一部、または新しい TPL データフロー ライブラリ、async/await 同時実行フレームワーク、および TPL の機能を詳述している他の作成者による、かなりの数の技術文書を読みました。ただし、どちらをいつ使用するかを明確に説明しているものに実際には遭遇していません。それぞれに独自の場所と適用性があることは認識していますが、具体的には次の状況に関して疑問に思います。

完全にインプロセスで実行されるデータ フロー モデルがあります。一番上にはデータ生成コンポーネント (A) があり、データを生成し、データ フロー ブロック リンケージを介して、または処理コンポーネント (B) にイベントを発生させることによってデータを渡します。(B) 内の一部の部分は同期的に実行する必要がありますが、(A) プロセスのほとんどは I/O または CPU バウンド (ディスクからバイナリ データを読み取り、それらを逆シリアル化して並べ替える) であるため、並列処理から大きなメリットがあります。最後に、処理コンポーネント (B) は変換された結果を (C) に渡し、さらに使用できるようにします。

具体的には、タスク、async/await、および TPL データ フロー ブロックをいつ使用するか、次の点で疑問に思います。

  • データ生成コンポーネント (A) を開始します。GUI/ダッシュボードをロックしたくないのは明らかなので、このプロセスは別のスレッド/タスクで実行する必要があります。

  • (A)、(B)、および (C) 内のメソッドを呼び出して、データの生成および処理プロセスに直接関与しないが、返されるまでに数百ミリ秒/秒かかる可能性のある構成作業を実行する方法。ここで async/await が活躍するというのが私の推測です。

  • 私が最も苦労しているのは、あるコンポーネントから次のコンポーネントに渡されるメッセージを最適に設計する方法です。TPL Dataflow は非常に興味深いように見えますが、私の目的には遅すぎる場合があります。(パフォーマンスの問題に関しては最後に注意してください)。TPL Dataflow を使用しない場合、インプロセスのタスク間/同時データ受け渡しによって応答性と同時実行性を実現するにはどうすればよいですか? たとえば、タスク内でイベントを発生させた場合、サブスクライブされたイベント ハンドラーは別のタスクに渡されるのではなく、同じタスクで実行されます。要約すると、コンポーネント (B) がデータを取得して処理に集中している間に、コンポーネント (B) にデータを渡した後、コンポーネント (A) はどのように業務を遂行できるのでしょうか? ここで使用するのに最適な同時実行モデルはどれですか? ここでデータ フロー ブロックを実装しましたが、それが本当に最善の方法でしょうか?

  • 上記の要約ポイントは、標準的な手法を使用して API タイプのコンポーネントを設計および実装する方法に苦労していると思いますか? メソッドを非同期に設計し、データ入力をデータ フロー ブロックとして設計し、データ出力をデータ フロー ブロックまたはイベントとして設計する必要がありますか? 一般的に最善のアプローチは何ですか?上記のコンポーネントのほとんどは独立して動作するはずなので、本質的にスワップアウトしたり、アクセサーや出力を書き直さなくても内部で個別に変更できるため、質問しています。

パフォーマンスに関する注意: TPL Dataflow ブロックが遅い場合があると述べました。私は高スループット、低レイテンシのタイプのアプリケーションとターゲット ディスク I/O 制限を扱っているため、tpl データフロー ブロックは、同期処理ユニットなどよりもはるかに低速で実行されることがよくあります。問題は、プロセスを独自のタスクまたは並行モデルに埋め込んで、tpl データフロー ブロックが既に処理しているものと同様のものを実現する方法がわからないことですが、tpl df に伴うオーバーヘッドはありません。

4

1 に答える 1

12

「プッシュ」システムがあるようです。プレーンasyncコードは、「プル」シナリオのみを処理します。

あなたの選択は TPL Dataflow とRxの間です。TPL Dataflow の方が習得しやすいと思いますが、既に試したことがあり、自分の状況ではうまくいかないので、Rx を試してみます。

Rx は、非常に異なる視点から問題に取り組んでいます。TPL Dataflow の「アクターのメッシュ」ではなく、「イベントのストリーム」を中心にしています。Rx の最近のバージョンは非常に使いやすいため、Rx パイプラインのいくつかのポイントでデリゲートをasync使用できます。async

API 設計に関しては、TPL Dataflow と Rx の両方が、実装する必要があるインターフェイスを提供します: IReceivableSourceBlock/ ITargetBlockTPL Dataflow 用、およびIObservable/ IObserverRx 用。実装を内部メッシュ (TPL データフロー) またはクエリ (Rx) のエンドポイントに接続するだけです。そうすれば、コンポーネントは、他の「メッシュ」または「クエリ」で構成できる単なる「ブロック」または「オブザーバブル/オブザーバー/サブジェクト」になります。

最後に、async構築システムでは factory パターンを使用するだけです。実装はTask.Run、スレッド プール スレッドで構成を行うために呼び出すことができます。

于 2012-11-27T13:01:58.017 に答える