首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows服务的并行编程

Windows服务的并行编程
EN

Stack Overflow用户
提问于 2015-10-01 17:03:21
回答 1查看 823关注 0票数 3

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

代码语言:javascript
复制
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+连接的峰值,而我们的服务器会停止运行。

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

我怀疑上面的代码是造成我们的可伸缩性问题的原因。考虑到Windows (无UI)上的这种使用场景( I/O操作的并行性),Parallel.ForEach是最好的方法吗?我对异步编程没有太多的经验,我期待着利用这个机会来了解更多关于异步编程的知识,我想我应该从这里开始获得一些社区建议,以补充我在Google上找到的东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-01 17:14:50

Parallel.Foreach有一个可怕的设计缺陷。随着时间的推移,它容易消耗所有可用的线程池资源。它将产生的线程数量实际上是无限的。在没有人理解的启发式驱动下,每秒最多可以得到两个新的。CoreCLR有一个爬山算法,只是不起作用。

呼叫外部服务

也许,您应该找出调用该服务的正确并行度。你需要通过测试不同的数量来找到答案。

然后,您需要将Parallel.Foreach限制为最多只生成多少个线程。您可以使用固定的并发性TaskScheduler来实现这一点。

或者,您可以将其更改为使用异步IO并使用SemaphoreSlim.WaitAsync。这样就不会阻塞线程。解决了池耗尽以及外部服务的重载问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32893034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档