從MSDN文檔我看到Unitys的IContainer解決方法不是線程安全的(或不寫)。這意味着你需要從線程循環中完成。編輯:改爲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");
}
另外,正如fiver所述,如果你有.Net 4,那麼任務就是要走的路。
爲什麼去工作(在評論的問題):
如果你的方法fromClientRequest會被瘋狂往往被炒了,你將填補線程池,和整體系統性能可能不會像在.NET 4中有良好細粒化。這是任務進入遊戲的地方。每個任務不是它自己的線程,但是新的.Net 4線程池創建足夠的線程來最大化系統性能,並且不需要打擾多少個cpus和多少線程上下文切換。
一些MSDN行情線程池:
當所有線程池中的線程已經 分配給任務,線程池 不會立即開始創建新 空閒線程。爲避免 不必要地爲線程分配堆棧空間 ,它會間隔創建新的空閒線程 。間隔爲 ,目前爲半秒,但它在 .NET Framework的未來版本中可能會發生更改 。
線程池具有的每間可用 處理器
250工作線程默認大小增加不必要的 空閒線程數也可能導致 性能問題。堆棧空間必須爲每個線程分配 。如果太多 許多任務同時開始,它們的所有 可能看起來很慢。 尋找合適的餘額是 性能調整問題。
通過使用任務,您可以放棄這些問題。
另一件好事是你可以細化運行類型的操作。如果您的任務運行阻止操作,這一點很重要。這是一個更多線程同時分配的情況,因爲他們大多會等待。線程池不能自動地實現這一點:
Task.Factory.StartNew(() => DoSomeWork(), TaskCreationOptions.LongRunning);
當然,你可以讓它完成需求,而不訴諸ManualResetEvent的:
var task = Task.Factory.StartNew(() => DoSomeWork());
task.Wait();
除了這個你不必改變Parallel.ForEach如果您不希望出現異常或阻止,因爲它是.Net 4任務並行庫的一部分,並且(通常)可以很好地在.NET 4池上運行並進行優化,就像任務一樣。
但是,如果您確實轉到Tasks而不是parallel for,請從調用程序Task中刪除LongRunning,因爲Parallel.For是阻止操作,啓動任務(包含fiver循環)不是。但是,這種方式可能會導致先到先得的優化失敗,或者您必須在更多的任務(全部通過ID生成)上執行這些任務,否則這些任務可能會導致更少的正確行爲。另一種選擇是等待DoSomeWorkInParallel結尾的所有任務。
我知道它只是僞代碼,但請告訴我你不會實例化你的倉庫(從IOC容器)在你的lambda內.. –
不,它已經存在,它是一個單身人士。 –