2017-05-20 38 views
-1

我們正在開發WebAPI,其中有大約200個項目的解密邏輯(可以更多)。每次解密大約需要20ms。 我們試着平行完成這些任務,以便儘快完成任務,但看起來我們正在獲得某種限制,因爲線程正在等待舊線程完成而被重用(並且在那裏只有少數人使用) - 總體行動需要大約1-2秒鐘才能完成......WebAPI中的線程(任務)限制(或一般情況下)

我們基本上想要達到的目標是讓x個線程同時啓動並在這些〜20 ms之後完成。

我們嘗試了這一點: Await multiple async Task while setting max running task at a time

但似乎這只是說明設置限制,而我們要釋放它...

這裏有一個片段:

    var tasks = new List<Task>(); 
        foreach (var element in Elements) 
        { 
         var task = new Task(() => 
         { 
          element.Value = Cipher.Decrypt((string)element.Value); 
         } 
         }); 
         task.Start(); 
         tasks.Add(task); 
        } 
        Task.WaitAll(tasks.ToArray()); 

是我們在這裏失蹤?

謝謝, Nir。

+2

除非您正在編寫任務調度程序,否則不應該調用'新任務('),而應該使用'Task.Run'。 –

回答

1

我不能推薦並行的ASP安排。淨。它肯定會影響你的服務的可擴展性,特別是如果它是面向公衆的。我曾經想過,「哦,我很聰明,能夠做到這一點」幾次,並在ASP.NET應用程序中增加了並行性,只是在一週後不得不把它撕掉。

不過,如果你真想到...

看來我們得到某種形式的限制

是你的計算機上的物理內核的限制嗎?

我們嘗試這樣的:等待或多個異步任務而在一個時間

即解決方案是專門爲異步並行代碼(例如,I/O約束)設置最大運行的任務。你想要的是並行(線程化)併發代碼(例如,CPU綁定)。完全不同的用例和解決方案。

我們在這裏失蹤了什麼?

您當前的代碼在線程池中拋出了大量的同步任務,這些任務將嘗試儘可能地處理它們。您可以通過使用更高級別的抽象(例如,,Parallel

Parallel.ForEach(Elements, element => 
{ 
    element.Value = Cipher.Decrypt((string)element.Value); 
}); 

Parallel處於其分區和(重新)使用線程(即,不超過核數)方面更加智能化。所以你應該看到一些加速。

但是,我希望它只是一個小的加速。您可能受限於您的物理內核數量。

0

Asuming無超線程:

如果需要20ms的1項,那麼你可以看看它,如果它需要1個核心爲20ms。如果你想在20毫秒內完成200個項目,那麼你需要200個核心。如果你沒有那麼多,它只是不能做......

在正常surcumstances,許多任務將作爲平行最適合你的系統

相關問題