【问题标题】:Handle x amount of thread every interval每个间隔处理 x 个线程
【发布时间】:2017-09-14 11:11:41
【问题描述】:

我有一个使用另一个系统的 API 的方法。我的系统在数据列表上运行,并为列表中的每个项目创建一个线程,向其他系统发出请求。 只有一个问题,另一个系统每次可以处理 x 数量的请求。 例如,每 2 分钟处理 5 个请求。 实施它的最佳实践是什么?假设我只想遍历列表一次。

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

【问题讨论】:

  • 请更新您的帖子以显示您现有的代码。
  • @Sinatr,我不确定他在问什么,但这似乎是一个完全不同的问题
  • 如果每 2 分钟不能超过 5 个请求,为什么还要使用多个线程?
  • 如果你不能超过每分钟一定数量的请求,为什么还要使用多个线程?

标签: c# multithreading thread-safety


【解决方案1】:

您可以通过多种方式做到这一点。也许最简单的方法是在调用之间执行Thread.Sleep() 的单线程。

每 2 分钟 5 个请求相当于每 24 秒 1 个请求。所以你可以写:

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,并让回调方法执行请求。

这两种技术都可以防止您过快地发出请求,而且它们很容易编写代码。

【讨论】:

  • 如果有 5 个请求要执行,每个请求需要 3 秒执行,那么这个实现执行这 5 个请求需要多长时间?
  • @mjwills:每个请求大约需要 27 秒。正如我所说,实际时间是 24 秒加上请求时间。我还指出,您可以通过从睡眠时间中减去最后一次请求时间来轻松解决这个问题。也许我会补充一点。哦,基于计时器的替代方案不会受到您指出的问题的影响。
  • 那么大约 99 秒 (24 * 4 + 3)?是否可以一次运行所有 5 个并在总共 3 秒内完成它们?
  • @mjwills:当然可以并行执行所有请求,然后等待 2 分钟再执行。我发现随着时间的推移将请求分开更容易。结果几乎相同。唯一的区别是,一种方式会比另一种方式提前两分钟完成。当您以每 24 秒一个的速度发出数千个请求时,那两分钟并不是很重要。
  • @roybarak:这是影响解决方案的相当重要的信息。请编辑您的问题并添加该信息。我会修改我的答案来解决这个问题。
【解决方案2】:

您不妨考虑使用Parallel.ForEach 来遍历列表。

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

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

ConcurrentLimitedCollection 可用here

【讨论】:

  • 谢谢我会检查这个解决方案
  • 一个相当简单的问题的复杂解决方案,你不觉得吗?
  • @JimMischel 感谢您的反馈。你觉得它的哪一部分很复杂?作为替代方案,您有什么建议?
  • 我确实添加了一个替代方案。不,我不是拒绝你答案的人。我在这里唯一的建议是重新阅读 OP 的问题并确定它是否真的需要线程。
  • 我不会说它需要线程。它是否受益于线程?好吧,我只能假设 OP 已经在使用它。 :P 如果每个时间窗口的请求数量较少(例如,如果限制为每 2 分钟 5 个,则线程几乎肯定会导致更快的响应时间)。
猜你喜欢
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 2012-08-20
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多