0

私は TPL を初めて使用するので、ここで戦略的なヘルプを探しています。

状況

互いに通信しない 2 つの異なる LOB システム間でデータを調整するアプリケーションがあります。したがって、次のようになります。

[ System 1 ] < ----- [ App ] ----- > [ System 2 ]

処理中、アプリは次のタスクを実行します。

  1. アプリはシステム 1 への接続を作成します。この接続は Web アプリケーションをスクリーン スクレイピングする必要があるため、システム 2 を使用して、それぞれが利用可能であることを確認します。
  2. アプリがシステム A に ID のリストを要求します。
  3. このリストは項目ごとに実行されます。そのリストの処理:
    1. アプリはシステム 1 からデータを要求します。このシステムはサービス インターフェイスを提供しないため、アプリは WebRequest を使用して、システム 1 への GET 要求と POST 要求の両方を行います。スクレイピングされた Web ページ データに加えて、ファイルをダウンロードすることもできます。
    2. システム 1 からのデータを使用して、アプリは複数の Web サービス呼び出しを介してシステム 2 にデータを送信します。いくつかの呼び出しが行われる可能性があり、ファイルがアップロードされる可能性があります。

多くの場合、ループには何万ものアイテムがあります。これらの項目間には依存関係がないため、 にTask基づく処理に適しているようです。

ただし、最大で、システム 1 への接続は約 20、システム 2 への接続は約 10 です。したがって、ループ内の各項目に対してセッションを作成および破棄するだけの単純なアイデア (単純な で行う場合と同様Parallel.ForEach Task) は、次のようになります。法外に費用がかかります。むしろ、接続を共有して、ある種の接続プールを作成したいと考えています。そのプールは、タスクが開始される前に作成されます。それぞれTaskが作業を開始すると、基本的にプールから接続を取得できるまで待機します。タスクが完了すると、接続が解放され、別のユーザーが接続をTask取得できます。この場合、スケジューラの制限は CPU だけではありません。それも最大数システム 2 への接続の。

欲望

アプローチを探しています。実装を理解するための作業を行うことは気にしませんが、最善の戦略的アプローチが必要です。

これらの限られた数の接続でタスク ループを動作させるにはどうすればよいですか? それとも、古いスタイルのスレッド割り当てに戻り、スレッドがタスクを完了するときに解放された接続を手動で渡す必要がありますか? ある種のミューテックス配列?もしそうなら、タスクはどのようにして開いている接続を取得しますか? ある種の並行バッグですか、それとも間違った方向に進んでいますか?

どんな助けでも歓迎です。

4

1 に答える 1

0

BlockingCollection接続プールごとにうまく機能すると思います。スレッドが空のプールから接続を取得しようとすると、別のスレッドがプールに接続を返すまで、そのスレッドはブロックされます。

MaxDegreeOfParallelism不必要に多くのスレッドが存在しないことを確認するために、より大きなプールのサイズにも設定する必要があります。それらのほとんどは、プールからの接続を取得するために待機しています。

これにより、コードは次のようになります。

var connection = serviceAConnections.Take();

// use the connection

serviceAConnections.Add(connection);

しかし、より良いアプローチは、それ以上に抽象化のレベルを追加することかもしれません:

using (var connectionHolder = serviceAConnections.Get())
{
   var connection = connectionHolder.Connection;

   // use the connection
}
于 2013-05-09T13:19:38.183 に答える