每隔一段时间处理x个线程

时间:2017-09-14 11:11:41

标签: c# multithreading thread-safety

我有一个使用另一个系统的API的方法。我的系统在一个数据列表上运行,对于列表中的每个项目,它创建一个请求到另一个系统的线程。 只有一个问题,另一个系统每隔一段时间就可以处理x个请求。 例如,每2分钟处理5个请求。 实施它的最佳做法是什么?假设我只想在列表上运行一次。

为了更清楚,让我说我通过互联网接近一些服务,这个服务允许我每2分钟发送5个请求,我有一个x行1000行,每行是一个请求我想读这个xml并发送请求,但我不希望其他系统拒绝我,我想每2分钟发送5个请求。 谢谢。

2 个答案:

答案 0 :(得分:0)

您可以通过多种方式实现这一目标。也许最简单的是在调用之间执行Thread.Sleep()的单个线程。

每2分钟发出5个请求,每24秒就有一个请求。所以你可以写:

while (requests remaining)
{
    make next request
    Thread.Sleep(TimeSpan.FromSeconds(24));
}

实际上,每24秒给你一个请求加上请求时间。如果您希望它完全是24秒,那么您必须计算发出请求所需的时间,并从延迟中减去该值。

这是你如何做到的:

while (requests remaining)
{
    var sw = Stopwatch.StartNew();
    make next request
    sw.Stop();
    var sleepTime = 24000 - sw.ElapsedMilliseconds;
    Thread.Sleep(sleepTime);
}        

另一种方法是使用计时器。这样可以节省您不得不一直等待一个线程。创建一个24秒周期的System.Threading.Timer,并让回调方法执行请求。

这两种技术都会阻止您过快地提出请求,并且它们很容易编码。

答案 1 :(得分:-1)

您可能希望考虑使用Parallel.ForEach来迭代列表。

您还应将MaxDegreeOfParallelism设置为5到limit the number of threads

您还需要根据您的要求,每2分钟(手动)跟踪通话次数。最简单的方法是将每个请求的开始DateTime存储在ConcurrentLimitedCollection<DateTime>中。如果是ConcurrentLimitedCollection.CurrentSize == 5,那么您需要验证过去的第一个条目至少是2分钟。

ConcurrentLimitedCollection可用here