我正在使用.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