gpt4 book ai didi

c# - Windows服务的并行编程

转载 作者:行者123 更新时间:2023-11-30 16:05:57 24 4
gpt4 key购买 nike

我有一个 Windows 服务,其代码类似于以下内容:

List<Buyer>() buyers = GetBuyers();
var results = new List<Result();

Parallel.Foreach(buyers, buyer =>
{
// do some prep work, log some data, etc.

// call out to an external service that can take up to 15 seconds each to return
results.Add(Bid(buyer));
}

// Parallel foreach must have completed by the time this code executes
foreach (var result in results)
{
// do some work
}

这一切都很好,也很有效,但我认为我们遇到了可伸缩性问题。我们平均每分钟 20-30 个入站连接,每个连接都会触发此代码。每个入站连接的“买家”集合可以包含 1-15 个买家。有时,我们的入站连接数会激增至每分钟 100 多个连接,然后我们的服务器就会停止运行。

每台服务器(两台负载平衡的 8 核服务器)的 CPU 使用率只有 50% 左右,但线程数继续增加(进程中的线程数激增至 350 个),我们对每个入站连接的响应时间从 3- 4 秒到 1.5-2 分钟。

我怀疑上面的代码导致了我们的可伸缩性问题。鉴于 Windows 服务(无 UI)上的这种使用场景(I/O 操作的并行性),Parallel.ForEach 是最好的方法吗?我在异步编程方面没有太多经验,我期待着利用这个机会了解更多相关信息,我想我会从这里开始获得一些社区建议,以补充我在 Google 上找到的内容。

最佳答案

Parallel.Foreach 有一个可怕的设计缺陷。随着时间的推移,它很容易耗尽所有可用的线程池资源。它将产生的线程数量实际上是无限的。在无人理解的启发式驱动下,您每秒最多可以获得 2 个新的。 CoreCLR 内置了一个无法正常工作的爬山算法。

call out to an external service

您可能应该找出调用该服务的正确并行度是多少。您需要通过测试不同的量来找出答案。

然后,您需要限制 Parallel.Foreach 最多只生成您想要的线程数。您可以使用固定并发 TaskScheduler 来做到这一点。

或者,您将其更改为使用异步 IO 并使用 SemaphoreSlim.WaitAsync。这样就没有线程被阻塞。池耗尽由此解决,外部服务过载也得到解决。

关于c# - Windows服务的并行编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32893034/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com