我正在使用.Net構建股票報價更新程序。假設在上市時間內有X個股票代碼需要更新。爲了保持更新速度不超過數據提供者的限制(例如雅虎財務),我將嘗試通過使用類似於線程池的機制來限制請求數/秒。假設我想只允許5個請求/秒,對應於5個線程池。使用任務並行庫處理頻繁的URL請求
我聽說過TPL並希望使用它,雖然我沒有經驗。我如何在任務中指定隱式使用的池中的線程數?這裏是一個循環來安排請求,其中requestFunc(url)是更新引號的函數。我喜歡從專家那裏得到一些意見或建議,正確地做到這一點:
// X is a number much bigger than 5
List<Task> tasks = new List<Task>();
for (int i=0; i<X; i++)
{
Task t = Task.Factory.StartNew(() => { requestFunc(url); }, TaskCreationOptions.None);
t.Wait(100); //slow down 100 ms. I am not sure if this is the right thing to do
tasks.Add(t);
}
Task.WaitAll(tasks);
好的,我添加了一個外部循環,使其連續運行。當我對@ steve16351的代碼做一些修改時,它只會循環一次。爲什麼????
static void Main(string[] args)
{
LimitedExecutionRateTaskScheduler scheduler = new LimitedExecutionRateTaskScheduler(5);
TaskFactory factory = new TaskFactory(scheduler);
List<string> symbolsToCheck = new List<string>() { "GOOG", "AAPL", "MSFT", "AGIO", "MNK", "SPY", "EBAY", "INTC" };
while (true)
{
List<Task> tasks = new List<Task>();
Console.WriteLine("Starting...");
foreach (string symbol in symbolsToCheck)
{
Task t = factory.StartNew(() => { write(symbol); },
CancellationToken.None, TaskCreationOptions.None, scheduler);
tasks.Add(t);
}
//Task.WhenAll(tasks);
Console.WriteLine("Ending...");
Console.Read();
}
//Console.Read();
}
public static void write (string symbol)
{
DateTime dateValue = DateTime.Now;
//Console.WriteLine("[{0:HH:mm:ss}] Doing {1}..", DateTime.Now, symbol);
Console.WriteLine("Date and Time with Milliseconds: {0} doing {1}..",
dateValue.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), symbol);
}
是否要限制爲5個/秒或5個併發操作? – i3arnon
是的,我主要關心的是請求的數量,因爲我的IP可能會被阻止,如果我超過數據提供商的限制太長時間/頻繁。只要系統允許,線程是次要的。 –
是的,這是處理外部服務時常見的限制。 TPL Dataflow非常適合這一點。 – i3arnon