2015-11-05 73 views
8

我想創建一個WebApi方法,該方法運行一系列難以進一步優化的循環計算。單個ASP.net請求的多個核心

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

當此代碼執行時,通過查看服務器的任務管理器,似乎它只是馬克塞斯單個處理器核心,而讓其他核心不變。

從我讀到的,asp.net限制了一個處理器核心的單個請求。由於這是一個很少有整體請求的Intranet服務器,我不關心管理服務器資源。

是否有任何方法來覆蓋或解決此行爲,使我的循環運行速度更快?

+2

你試過設置MaxDegreeOfParallelism選項?平行。ForEach(Items,new ParallelOptions(){MaxDegreeOfParallelism = Environment.ProcessorCount},item => {...}); –

+0

有沒有反正你可以設計你的循環,並啓動不同的線程來傳播負載。所以如果你有一個1000件物品的集合,就會爲第一個500個線程啓動一個線程,爲剩下的500個線程啓動另一個線程? – WooHoo

+0

@SK似乎解決了這個問題,但我不知道爲什麼,因爲我認爲PLinq ForAll應該使用最大可用資源。也許這在asp.net下是不同的。 – phosplait

回答

1

ASP.Net可以非常簡潔地限制TPL使用的線程數。只需創建一個TaskScheduler,該TaskScheduler僅限於一個線程,並在給定的TaskScheduler上啓動ASP.Net請求。我敢打賭,他們將有這些有限的TaskScheuler的游泳池,它將使意義......

然後將當你調用TPL還是PLINQ任務處理ASP.Net請求裏面發生什麼事?

它是使用對Task.Start的調用甚至更好的調度任務,並且通過TPL團隊更優選的方式Task.Factory.StartNew。

但是,但是,巴特:)TaskScheduler.Current之上,這些計劃任務,這是我們已經運行我們有限的TaskScheduler!因此,無論您的計算機有多少核心,所有計劃的任務都將在有限的TaskScheduler上被刻錄。另一方面,似乎異步/等待操作正在使用.Net 4.5+中引入的新Task.Run(),並且建議它在TashScheduler.Default上調度任務,什麼是ThreadPool本身,所以沒有限制,除了核心數量。我沒有證據比這導致其他雖然:)Regarding usage of Task.Start() , Task.Run() and Task.Factory.StartNew() TPL

不幸的是進行AsParallel(有沒有超載採取的TaskScheduler。

因此,解決辦法是:

  1. 已經@Sķ提出的第一個,使用類並行,並指定並行度。該類早於PLINQ,並且正在使用ThreadPool。
  2. 第二個想法是自己調度ThreadPool。
  3. 或在TaskScheduler.Default上安排任務,目標是ThreadPool。
  4. 還是釀出自己的線程(最糟糕的主意)用於ASP.Net。
  5. 或者使用async/await在TaskScheduler.Default上運行工作,ThreadPool和async方法中使用AsParalel(),因爲TaskScheduler.Current與TaskScheduler.Default相同,只是ThreadPool。

注意事項:請注意,在ASP.Net線程池調度重的東西可以導致處理ASP.Net請求的性能下降...

相關問題