。これはスレッドループからそれを行う必要があることを意味します。編集:Task
に変更されました。
public void FromWebClientRequest(int[] ids);
{
IRepoType repoType = container.Resolve<IRepoType>();
ILogger logger = container.Resolve<ILogger>();
// remove LongRunning if your operations are not blocking (Ie. read file or download file long running queries etc)
// prefer fairness is here to try to complete first the requests that came first, so client are more likely to be able to be served "first come, first served" in case of high CPU use with lot of requests
Task.Factory.StartNew(() => DoSomeWorkInParallel(ids, repoType, logger), TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness);
}
private static void DoSomeWorkInParallel(int[] ids, IRepoType repository, ILogger logger)
{
// if there are blocking operations inside this loop you ought to convert it to tasks with LongRunning
// why this? to force more threads as usually would be used to run the loop, and try to saturate cpu use, which would be doing nothing most of the time
// beware of doing this if you work on a non clustered database, since you can saturate it and have a bottleneck there, you should try and see how it handles your workload
Parallel.ForEach(ids, id=>{
// Some work will be done here...
// use repository
});
logger.Log("finished all work");
}
また、あなたが.Net 4を持っている場合は、タスクが進む方法です。
なぜタスク(コメントで質問を)行く:
あなたの方法fromClientRequestがめちゃくちゃしばしば解雇されるだろう場合は、スレッドプールを埋めるだろう、とシステム全体のパフォーマンスは、おそらくによる.NET 4と同様に良好ではないでしょう細かい砂目立て。これはタスクがゲームに入る場所です。各タスクは独自のスレッドではありませんが、新しい.Net 4スレッドプールはシステム上のパフォーマンスを最大限にするのに十分なスレッドを作成し、CPUの数とスレッドコンテキストスイッチの量を気にする必要はありません。
いくつかのMSDNはThreadPoolのため引用:
すべてのスレッドプールのスレッドがタスクに を割り当てられている場合は、スレッドプール はすぐに 新しいアイドルスレッドの作成を開始しません。 がスレッドのためにスタック領域 を不必要に割り当てるのを避けるため、間隔を空けて新しいアイドル スレッドを作成します。現在、 は、 .NET Frameworkの将来のバージョンで変更される可能性がありますが、現在の間隔は です。
スレッドプールは、不必要にも パフォーマンス上の問題を引き起こす可能性があります アイドルスレッドの数を増やす可能な プロセッサ
あたり 250ワーカースレッドのデフォルトサイズを持っています。スタック空間は、各スレッドに対して を割り当てる必要があります。 多くのタスクが同時に開始される場合は、 のすべてが遅く表示されることがあります。 正しいバランスを見つけることは、 パフォーマンスチューニングの問題です。
タスクを使用することで、これらの問題を破棄します。
別の良いことは、実行する操作の種類を細かくすることができることです。タスクがブロック操作を実行する場合、これは重要です。これは、ほとんどのスレッドが同時に待機するため、より多くのスレッドを同時に割り当てる場合です。 ThreadPoolのは、自動的にこれを達成することはできません。
Task.Factory.StartNew(() => DoSomeWork(), TaskCreationOptions.LongRunning);
そしてもちろん、あなたはそれがManualResetEventに頼ることなく、オンデマンドで終える作ることができます。この他に
var task = Task.Factory.StartNew(() => DoSomeWork());
task.Wait();
をあなたはParallel.ForEachを変更する必要はありません例外やブロックが予想されない場合は、.Net 4 Task Parallel Libraryの一部であり、(しばしば)正常に動作し、.Net 4プールで最適化されます。
ただし、ParallelではなくTaskに移動する場合、Parallel.Forはブロック操作であり、Startingタスク(fiverループあり)はLongRunningを呼び出し元タスクから削除します。しかし、このようにして先着順最適化を緩和するか、おそらくそれほど正しい動作を与えない多くのタスク(すべてのIDを通じて生成される)で実行する必要があります。別のオプションは、DoSomeWorkInParallelの最後にあるすべてのタスクを待機することです。
私はちょうど擬似コードを知っていますが、ラムダの内部で(IOCコンテナから)リポジトリをインスタンス化するつもりはないと教えてください。 –
いいえ、それはすでに存在し、それはシングルトンでした。 –