2015-11-05 2 views
8

さらに最適化することが難しい一連のループ計算を実行するWebApiメソッドを作成しようとしています。1つのASP.net要求の複数のコア

x.Items.AsParallel().ForAll(item => 
{ 
    item.RunCalcs(); 
}); 

このコードを実行すると、サーバ・タスク・マネージャを見て、そのまま他のコアを残して、それは単一のプロセッサ・コアをmaxesと思われます。

私が読んだところから、asp.netは1つの要求を1つのプロセッサコアに限定しています。これは全体的な要求が非常に少ないイントラネットサーバーなので、サーバーリソースの管理には関係しません。

ループを高速化するためにこの動作を無効にするか、回避する方法はありますか?

+2

あなたはMaxDegreeOfParallelismを設定しようとしたことがありオプション?平行。ForEach(Items、新しいParallelOptions(){MaxDegreeOfParallelism = Environment.ProcessorCount}、item => {...}); –

+0

ループを設計し、別のスレッドを起動して負荷を分散させることができますか?だから1000個のアイテムのコレクションを持っているなら、最初の500のスレッドを起動し、残りの500のスレッドを起動しますか? – WooHoo

+0

@SKが問題を解決しているようですが、PLinq ForAllが利用可能な最大限のリソースを使用すると考えられた理由はわかりません。おそらくそれはasp.netの下で異なっています。 – phosplait

答えて

1

ASP.Netは、TPLでも非常にきちんとした方法で使用されるスレッドの数を制限することができます。 TaskSchedulerを作成するだけで、1つのスレッドに限定され、指定されたTaskSchedulerでASP.Net要求が開始されます。私は、これらの限られたTaskScheulerのプールを持っているだろう、それは意味をなさないだろう...

次に、TPLまたはPLINQを呼び出すとASP.Net要求を処理するタスクの内部で何が起こるでしょうか?

Task.Startへの呼び出しを使用してタスクをスケジューリングしているか、さらにはTPLチームによって、Task.Factory.StartNewが優先されます。

しかし、しかし、BUTT :)、これらはTaskScheduler.Currentの上にタスクをスケジュールしている、それは我々がすでに稼働している私たちの限られたTaskSchedulerです!そのため、スケジュールされたすべてのタスクは、マシンのコア数に関係なく、限られたTaskSchedulerで焼き付けられます。

一方、async/await操作では、.Net 4.5+で導入された新しいTask.Run()が使用されているようで、TashScheduler.Defaultのタスクスケジューリングであることが示唆されました。ThreadPool自体、コアの数以外の制限はありません。私はこの鉛以外の証拠はありません:Regarding usage of Task.Start() , Task.Run() and Task.Factory.StartNew() TPL

残念ながら、AsParallel()はTaskSchedulerを使って過負荷がありません。

だから、解決策は次のようになります。

  1. すでに@S Kによって提案された最初の1、クラスパラレルを使用し、並列度を指定します。クラスはPLINQに先行し、それが合うようにThreadPoolを使用しています。
  2. 2番目のアイデアは、自分でThreadPoolをスケジュールすることです。
  3. または、TaskScheduler.Defaultでタスクをスケジュールし、ThreadPoolを対象とします。
  4. ASP.Net用に独自のスレッドを作成することをお勧めします。
  5. TaskScheduler.Default、ThreadPool、およびasyncメソッドでAsync/awaitを使用すると、Asparalel()が使用されます。これは、TaskScheduler.CurrentがTaskScheduler.Defaultと同じで、単にThreadPoolになるためです。注意OF

注:ASP.NetでのThreadPoolの上に重いものをスケジュールすると、ASP.Netのリクエストを処理するの減少パフォーマンスにつながることができ、注意してください...

関連する問題