本文介绍了C# - 何时在高活动服务器中使用标准线程、线程池和 TPL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近阅读了很多关于线程的文章,因为我希望开发一种高性能、可扩展的 TCP 服务器,该服务器能够处理多达 10,000-20,000 个客户端,其中每个客户端始终与服务器进行双向通信基于命令的系统.服务器将接收一个命令,并根据该命令执行一个(或多个)任务.我的问题是如何在各种情况下适当地利用 .NET 线程构造,执行可能需要一分钟到几个小时的任务,具体取决于正在执行的工作.

I've been reading a lot about threading lately as I am looking to develop a high-performance, scalable TCP server capable of handling up to 10,000-20,000 clients, each client of which is consistently communicating bidirectionally to the server with a command-based system. The server will receive a command, and execute either a single (or many) tasks as per the command. My question is how to appropriately make use of the .NET threading constructs for a variety of situations, executing tasks that could take between one minute to several hours, depending on the work being performed.

最让我困惑的是,在我阅读的任何地方,我都看到类似使用手动创建的线程(或自定义线程池)来处理‘长时间运行’的任务,并使用 TPL 处理短期任务,或需要并行处理的任务."什么是长期运行的任务?那是 5 秒、60 秒还是一个小时?

What's confusing me the most is the fact that everywhere I read, I see something like "use a manually created Thread (or custom thread pool) to handle 'long-running' tasks, and use TPL for short-lived tasks, or tasks that require parallel processing." What exactly is a long-running task? Is that 5 seconds, 60 seconds, an hour?

我应该在什么时间范围内使用这三种创建线程的方法:

With what time frame should I be using each of these three methods of creating threads:

  • 手动创建线程
  • .NET 线程池类
  • TPL

我考虑的另一个问题如下——假设我的服务器实际上连接了 20,000 个客户端,每个客户端每秒发送 1 个命令(可以转换为一个或多个任务).即使拥有强大的硬件,我是否也有可能将过高的工作负载推入我拥有的任何线程池/工作项队列,从而在队列缓慢填充到最大值后最终生成 OutOfMemoryException?

Another issue I've contemplated is as follows--say my server does in fact have 20,000 clients connected, each of which sends 1 command (which could translate to one or many tasks) per second. Even with powerful hardware, isn't there a chance that I could be pushing too high of a workload into whatever thread pool / work item queue I have, thereby eventually generating an OutOfMemoryException after the queue slowly fills to the maximum?

任何见解将不胜感激.

推荐答案

实际上,对于那个场景所有都是次要的;你应该看的第一件事是 asyc-IO,又名 .BeginRead(...) 等;这允许您通过等待 IO 完成端口来最小化线程数 - 效率更高.

Actually, for that scenario all of those are secondary; the first thing you should look at is asyc-IO, aka .BeginRead(...) etc; this allows you to minimise the number of threads by waiting on IO completion ports - much more efficient.

一旦你有一个完整的消息,在那个规模我会把消息扔到一个自定义的线程池/同步队列中.我将有控制数量的常规线程(不是池线程或 IOCP)为该队列提供服务以处理每个项目.

Once you have a complete message, at that scale I would throw the message into a custom thread-pool/synchronized-queue. I would have a controlled number of regular threads (not pool threads or IOCP) servicing that queue to process each item.

碰巧我目前正在做类似的事情(规模较小);为了防止内存爆炸,我限制了工作队列;如果它已满(即工作人员无法跟上),那么您可能会阻止 IOCP 一小会儿,也许最终会超时,这会告诉客户端在 IOCP 层太忙".

As it happens I'm doing something similar (lower scale) at the moment; to prevent memory exploding, I have capped the work queue; if it gets full (i.e. the workers can't keep up) then you might block IOCP for a small while, perhaps with a timeout eventually that tells the client "too busy" at the IOCP layer.

这篇关于C# - 何时在高活动服务器中使用标准线程、线程池和 TPL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 07:08