i3arnonの答えは良いです。データフローは、特にCPUとI/Oバウンドコードが混在している場合に便利です。私はParallel
がCPUバウンドコード用に設計されているという彼の感想をエコーします。 I/Oベースのコードには最適なソリューションではなく、特には非同期コードには適していません。
あなたはほとんど-I/Oのコードでうまく動作の代替ソリューションをしたい場合は - と外部ライブラリを必要としない - あなたが探している方法はTask.WhenAll
です:
var tasks = uris.Select(uri => SendRequestAsync(uri)).ToArray();
await Task.WhenAll(tasks);
これは、最も簡単なソリューションですが、すべての要求を同時に開始するという欠点があります。特に、すべての要求が同じサービス(または少数のサービス)に向かう場合、タイムアウトが発生する可能性があります。これを解決するには、何らかのスロットルを使用する必要があります...
私は作成できる最大タスク数と最大HttpClientの数を制御する機能(TPLパーティショナーなど)はありますか?
TPL Dataflowには、一度に多くの数だけ開始するnice MaxDegreeOfParallelism
があります。代わりに、タスクを使用する場合には
private readonly SemaphoreSlim _sem = new SemaphoreSlim(50);
private async Task SendRequestAsync(Uri uri)
{
await _sem.WaitAsync();
try
{
...
}
finally
{
_sem.Release();
}
}
、それらの膨大な数を作成するためのベストプラクティスは何です:あなたはまた、別の組み込み、SemaphoreSlim
を使用することにより、通常の非同期コードを絞ることができますか? Task.Factory.StartNew()を使用してこれらのタスクをリストに追加し、すべてのタスクを待機するとしましょう。
実際にはStartNew
は使用しないでください。非常にまれな1つの適切なユースケース(動的タスクベースの並列処理)しかありません。バックグラウンドスレッドに作業をプッシュする必要がある場合は、最新のコードでTask.Run
を使用する必要があります。しかし、あなたはそれが最初に必要なことさえないので、StartNew
でもTask.Run
もここでは適切ではありません。
SOについても同様の質問がいくつかありますが、最大値は何も記載されていません。要件は、最大HttpClientで最大タスクを使用することです。非同期コードが本当にトリッキー取得する場所
最大値があります。 CPUバインド(パラレル)コードでは、解決策は明らかです。コアを持つスレッド数を使用します。 (まあ、少なくともあなたはそこを開始し、必要に応じて調整することができます)。非同期コードでは、ソリューションのように明白ではありません。あなたが持っているどのくらいのメモリ、リモートサーバーがどのように応答するか(レート制限、タイムアウトなど)など
ここでは簡単な解決策はありません - それは多くの要因に依存します。特定のアプリケーションが並行性の高いレベルをどのように処理しているかをテストし、次にいくつかの低い数値に絞り込むだけです。
私は異なる技術が適切であるときに説明しようとするいくつかの
slides for a talk持って(並列処理、非同期、TPLデータフローを、およびRx)。レシピで書かれた説明のほうが好きな人は、
my bookから同時性について恩恵を受けると思います。
同時要求の数を作ることができますhttpリクエスト・オペレーティング・システムの最大数を超えた場合はどうすれば
? – ozgur
@ozgurその制限がどこで設定されているかによって異なります。しかし、ある場合は、MaxDegreeOfParallelismをそれより低い値に設定してください。 – i3arnon
最後の質問。あなたが提供した例はIO操作に適していますが、CPUの並列処理は必要ありませんか? – ozgur